Iterable vs iterator Python

Iterables và Iterators thường bị nhầm lẫn với nhau, tuy nhiên, chúng là hai khái niệm khác biệt. Bài viết này sẽ giải thích sự khác biệt giữa hai loại này và cách chúng được sử dụng. Đầu tiên chúng ta hãy xem xét ngắn gọn Iteration là gì

Theo thuật ngữ của giáo dân, Lặp lại có nghĩa là 'các bước lặp lại'. Trong thuật ngữ lập trình, Lặp lại là sự lặp lại của một câu lệnh/khối mã một số lần cụ thể, tạo ra đầu ra lần lượt. Các phép lặp có thể được thực hiện bằng cách sử dụng các vòng lặp for chẳng hạn.  

 

Iterables trong Python

 
Iterables là các đối tượng có thể được lặp/lặp đi lặp lại bằng cách sử dụng vòng lặp for. Iterables chứa dữ liệu hoặc có giá trị, trong đó việc thực thi vòng lặp for sẽ thực hiện một phép lặp, tạo ra kết quả lần lượt.  

Một iterable thực hiện phương thức __iter__() và trả về một đối tượng iterator. Tuy nhiên, nếu phương thức __iter__() không được định nghĩa, Python sẽ sử dụng

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
0 để thay thế.  

Ví dụ về Iterables là danh sách, từ điển, chuỗi, bộ dữ liệu, v.v. Miễn là bạn có thể lặp lại nó, nó là một Iterable.  

Để tìm hiểu xem một đối tượng có thể lặp lại hay không, bạn sẽ phải kiểm tra xem nó có hỗ trợ

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
1. Để làm điều này, chúng tôi sử dụng hàm
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
2, trả về tất cả các thuộc tính và phương thức của đối tượng được chỉ định, ngoại trừ các giá trị.  

Mã ví dụ

class Person:
 name = "Nisha"
 age = 25
 country = "England"

print(dir(Person))


 
đầu ra

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']


 

Trình lặp trong Python

 
Một Iterator cũng là một đối tượng sử dụng các phương thức __iter__()

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
4, đây được gọi là giao thức Iterator. Nó là một đối tượng có thể lặp lại với một trạng thái, nghĩa là nó ghi nhớ nó đang ở giai đoạn nào trong quá trình lặp lại.  

Iterator trả về giá trị, mỗi lần một phần tử. Khi giá trị tiếp theo của đối tượng Iterable được trả về, trạng thái của trình vòng lặp được cập nhật và biết cách lấy giá trị tiếp theo bằng phương thức

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
4. Iterators chỉ có thể di chuyển về phía trước, chúng không thể quay lại hoặc tự đặt lại.  

Các trình vòng lặp cũng đưa ra một ngoại lệ StopIteration khi không còn phần tử nào nữa hoặc đối tượng đã cạn kiệt.  

 
Mã ví dụ

Ở đây tôi đã tạo một trình vòng lặp có tên là 'số'. Tôi đã đặt một dòng mã để kiểm tra loại của nó. Chúng tôi đang mong đợi phép lặp sẽ xuất ra tất cả các số. Tuy nhiên, tôi đã yêu cầu nó in đầu ra thứ 6, mặc dù chỉ có 5 giá trị trong iterator. Hãy xem điều gì sẽ xảy ra

numbers = iter([2, 4, 6, 8, 10])

print(type(numbers))

print(next(numbers))
print(next(numbers))
print(next(numbers))
print(next(numbers))
print(next(numbers))
# The next() function will raise StopIteration as it is exhausted
print(next(numbers))


 
đầu ra

Chúng ta có thể thấy rằng loại là một 'list_iterator'. Đầu ra dừng ở 10 và tăng lên một

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
6 vì không còn phần tử nào trong danh sách số.  

<class 'list_iterator'>
2
4
6
8
10

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-15-0cb721c5f355> in <module>()
     11 
     12 # The bext() function will raise StopIteration as it is exhausted
---> 13 print(next(numbers))

StopIteration:


 
Hạn chế của Iterator

  1. Trình vòng lặp chỉ di chuyển theo hướng thuận, chúng không quay ngược hoặc đặt lại
  2. Không thể sao chép các trình vòng lặp vì nó là đối tượng một chiều chỉ có thể di chuyển về phía trước
  3. Do hướng một chiều, không có cách nào để truy xuất phần tử trước đó.  

 

Điểm tương đồng và khác biệt giữa Iterables và Iterators

 

IterableIterator Lặp lại bằng cách sử dụng. vòng lặp for vòng lặp for Phương pháp được sử dụng. __iter__()    __iter__() và __next__()

 

Iterator là một Iterable, vì nó cũng triển khai phương thức __iter__().  

Nhớ. Mọi Iterator đều là Iterable, tuy nhiên không phải Iterable nào cũng là Iterator.  

 
Ví dụ về

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
2 của một Iterable

numbers = [2, 4, 6, 8, 10]

print(dir(numbers))


 
đầu ra

Trong kết quả này, tôi đã đánh dấu

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
1, cho thấy rằng đó là một phương thức của Iterable

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', 
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', 
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', 
'__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 
'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']


 
Ví dụ về

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
2 của một Iterator

Trong ví dụ này, chúng tôi đang lặp lại danh sách số.  

numbers = [2, 4, 6, 8, 10]
numbers2 = iter(numbers)

print(dir(numbers2))


 
đầu ra

Trong kết quả này, tôi đã đánh dấu

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'__weakref__', 'age', 'country', 'name']
1 và
numbers = iter([2, 4, 6, 8, 10])

print(type(numbers))

print(next(numbers))
print(next(numbers))
print(next(numbers))
print(next(numbers))
print(next(numbers))
# The next() function will raise StopIteration as it is exhausted
print(next(numbers))
2, cho thấy rằng đó là một phương thức của Iterator

['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', 
'__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', 
'__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', 
'__subclasshook__']


Tôi hy vọng blog ngắn này đã giúp bạn hiểu rõ hơn về sự khác biệt giữa Iterable và Iterator

Có phải mỗi iterable là một iterator Python không?

Ghi chú. Mọi trình lặp cũng là một trình lặp, nhưng không phải mọi trình lặp đều là một trình lặp trong Python . Ví dụ: một danh sách có thể lặp lại nhưng một danh sách không phải là một trình vòng lặp. Một iterator có thể được tạo từ một iterable bằng cách sử dụng hàm iter().

Sự khác biệt giữa giao diện iterable và giao diện iterator là gì?

Iterable không lưu trữ bất kỳ trạng thái lặp nào . Trạng thái lặp là con trỏ tới phần tử trong bộ sưu tập mà trình lặp sẽ trả về tiếp theo. Ví dụ Iterator duy trì trạng thái lặp. Điều này có nghĩa là người dùng có thể kiểm tra xem phần tử tiếp theo có tồn tại hay không, chuyển sang phần tử tiếp theo, v.v.

Iterator là Iterable?

Ngoài ra, bản thân Iterator là một Iterable vì nó cũng phải triển khai phương thức __iter__() trong đó nó chỉ trả về self

Sự khác biệt giữa iterator và for loop trong Python là gì?

Sức mạnh bộ lặp cho các vòng lặp . Iterators là thứ cung cấp năng lượng cho iterables. Bạn có thể nhận một iterator từ bất kỳ iterable nào. Và bạn có thể sử dụng một trình vòng lặp để lặp thủ công vòng lặp mà nó đến từ. Python's for loops use iterators. Iterators are the things that power iterables. You can get an iterator from any iterable. And you can use an iterator to manually loop over the iterable it came from.