Chính xác thì lặp, lặp và lặp là gì?


442

Định nghĩa cơ bản nhất của "iterable", "iterator" và "iteration" trong Python là gì?

Tôi đã đọc nhiều định nghĩa nhưng tôi không thể xác định ý nghĩa chính xác vì nó vẫn không chìm trong.

Ai đó có thể vui lòng giúp tôi với 3 định nghĩa trong điều khoản cư sĩ không?

Câu trả lời:


530

Lặp lại là một thuật ngữ chung để lấy từng mục của một cái gì đó, cái khác. Bất cứ khi nào bạn sử dụng một vòng lặp, rõ ràng hoặc ẩn, để đi qua một nhóm các mục, đó là lặp lại.

Trong Python, iterableiterator có ý nghĩa cụ thể.

Một iterable là một đối tượng có một __iter__phương thức trả về một iterator hoặc định nghĩa một __getitem__phương thức có thể lấy các chỉ mục tuần tự bắt đầu từ 0 (và tăng lên IndexErrorkhi các chỉ mục không còn hợp lệ). Vì vậy, một iterable là một đối tượng mà bạn có thể nhận được một iterator từ đó.

Một iterator là một đối tượng với phương thức next(Python 2) hoặc __next__(Python 3).

Bất cứ khi nào bạn sử dụng một forvòng lặp, hoặc map, hoặc hiểu danh sách, v.v. trong Python, nextphương thức được gọi tự động để lấy từng mục từ trình vòng lặp , do đó sẽ trải qua quá trình lặp .

Một nơi tốt để bắt đầu học sẽ là phần iterators của hướng dẫn và phần iterator của trang loại chuẩn . Sau khi bạn hiểu những điều cơ bản, hãy thử phần lặp trong phần Lập trình chức năng HOWTO .


1
Lưu ý rằng collections.abc.AsyncIteratorcác bài kiểm tra __aiter____anext__phương pháp. Đây là một bổ sung mới trong 3.6.
Janus Troelsen

1
@jlh tại sao __len__nhất thiết phải gắn với lặp? Làm thế nào để biết chiều dài của một cái gì đó giúp bạn lặp đi lặp lại nó?
Shadowtalker

2
@shadowtalker sẽ giúp biết chỉ mục nào hợp lệ, vì vậy bạn biết chỉ mục nào có thể được sử dụng __getitem__.
jlh

4
@jlh Có vẻ như bạn đang đề xuất một hành vi dfeault rất quan tâm. Xem xét rằng {'a': 'hi', 'b': 'bye'}có độ dài bằng 2, nhưng không thể được lập chỉ mục bằng 0, 1 hoặc 2.
Shadowtalker

2
@shadowtalker. Nhưng một dict có một __iter__phương pháp. Tôi nghĩ rằng jlh đang đề cập đến các đối tượng có thể lặp lại cụ thể bởi vì chúng định nghĩa: "một __getitem__phương thức có thể lấy các chỉ mục tuần tự bắt đầu từ số không".
Giàu

337

Đây là lời giải thích tôi sử dụng trong việc dạy các lớp Python:

Một ITERABLE là:

  • bất cứ điều gì có thể được lặp lại (tức là bạn có thể lặp qua một chuỗi hoặc tệp) hoặc
  • bất cứ thứ gì có thể xuất hiện ở phía bên phải của vòng lặp for: for x in iterable: ...hoặc
  • bất cứ điều gì bạn có thể gọi với iter()điều đó sẽ trả lại một ITERATOR: iter(obj)hoặc
  • một đối tượng xác định __iter__trả về một ITERATOR mới hoặc nó có thể có một __getitem__phương thức phù hợp để tra cứu được lập chỉ mục.

Một ITERATOR là một đối tượng:

  • với trạng thái nhớ nó ở đâu trong khi lặp lại,
  • với một __next__phương pháp:
    • trả về giá trị tiếp theo trong lần lặp
    • cập nhật trạng thái để trỏ đến giá trị tiếp theo
    • tín hiệu khi nó được thực hiện bằng cách tăng StopIteration
  • và đó là tự lặp lại (có nghĩa là nó có một __iter__phương thức trả về self).

Ghi chú:

  • Các __next__phương pháp trong Python 3 được viết nextbằng Python 2, và
  • Hàm dựng sẵn next()gọi phương thức đó trên đối tượng được truyền cho nó.

Ví dụ:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable

bạn có ý nghĩa gì bởi iterator mới?
lmiguelvargasf 6/2/2017

13
@lmiguelvargasf "Tươi" như trong "mới và vô thức" trái ngược với "cạn kiệt hoặc tiêu thụ một phần". Ý tưởng là một trình vòng lặp mới bắt đầu từ đầu, trong khi một trình vòng lặp được sử dụng một phần sẽ chọn nơi nó rời đi.
Raymond Hettinger

Đạn thứ 2, 3 và 4 của bạn cho biết rõ ý của bạn là gì, về mặt cấu trúc python cụ thể hoặc các lệnh gọi phương thức hoặc tích hợp. Nhưng viên đạn thứ nhất ("bất cứ thứ gì có thể lặp lại") không có sự rõ ràng đó. Ngoài ra, viên đạn thứ 1 dường như có sự trùng lặp với viên đạn thứ 2, vì viên đạn thứ 2 là về forcác vòng lặp, và viên đạn thứ nhất là về "vòng lặp". Bạn có thể xin vui lòng giải quyết những?
fountainhead

2
Xin xem xét lại cụm từ "bất cứ điều gì bạn có thể gọi bằng iter()" là "bất cứ điều gì bạn có thể vượt qua iter()"
fountainhead

98

Các câu trả lời trên rất hay, nhưng như hầu hết những gì tôi đã thấy, đừng nhấn mạnh sự khác biệt đủ cho những người như tôi.

Ngoài ra, mọi người có xu hướng nhận được "quá Pythonic" bằng cách đặt các định nghĩa như "X là một đối tượng có __foo__()phương thức" trước đó. Các định nghĩa như vậy là chính xác - chúng dựa trên triết lý gõ vịt, nhưng trọng tâm của các phương pháp có xu hướng giữa khi cố gắng hiểu khái niệm này trong sự đơn giản của nó.

Vì vậy, tôi thêm phiên bản của tôi.


Trong ngôn ngữ tự nhiên,

  • lặp là quá trình lấy một phần tử tại một thời điểm trong một hàng các phần tử.

Trong Python

  • iterable là một đối tượng, tốt, lặp đi lặp lại, đơn giản chỉ có nghĩa là nó có thể được sử dụng trong phép lặp, ví dụ như với một forvòng lặp. Làm sao? Bằng cách sử dụng iterator . Tôi sẽ giải thích bên dưới.

  • ... trong khi iterator là một đối tượng xác định cách thực sự lặp lại - cụ thể phần tử tiếp theo là gì . Đó là lý do tại sao nó phải có next()phương pháp.

Các trình lặp cũng tự lặp lại, với sự khác biệt là __iter__()phương thức của chúng trả về cùng một đối tượng ( self), bất kể các mục của nó có được sử dụng bởi các lệnh gọi trước hay không next().


Vậy trình thông dịch Python nghĩ gì khi thấy for x in obj:câu lệnh?

Hãy nhìn xem, một forvòng lặp. Trông giống như một công việc cho một trình vòng lặp ... Hãy lấy một cái. ... Có objanh chàng này , vì vậy hãy hỏi anh ta.

"Ông obj, bạn có lặp lại không?" (... các cuộc gọi iter(obj), cuộc gọi này obj.__iter__(), vui vẻ đưa ra một trình vòng lặp mới sáng bóng _i.)

OK, thật dễ dàng ... Hãy bắt đầu lặp đi lặp lại. ( x = _i.next()... x = _i.next()...)

Vì Mr. objđã thành công trong bài kiểm tra này (bằng cách có một phương thức nhất định trả về một trình vòng lặp hợp lệ), chúng tôi thưởng cho anh ấy bằng tính từ: bây giờ bạn có thể gọi anh ấy là "ông lặp đi lặp lại obj".

Tuy nhiên, trong các trường hợp đơn giản, thông thường bạn không được hưởng lợi từ việc có trình vòng lặp và vòng lặp riêng biệt. Vì vậy, bạn chỉ xác định một đối tượng, đó cũng là trình lặp riêng của nó. (Python không thực sự quan tâm đến việc được _iđưa ra bởi objkhông phải là tất cả sáng bóng, mà chỉ là objchính nó.)

Đây là lý do tại sao trong hầu hết các ví dụ tôi đã thấy (và những gì đã làm tôi bối rối nhiều lần), bạn có thể thấy:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

thay vì

class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

Tuy nhiên, có những trường hợp khi bạn có thể hưởng lợi từ việc iterator tách khỏi iterable, chẳng hạn như khi bạn muốn có một hàng vật phẩm, nhưng nhiều "con trỏ" hơn. Ví dụ: khi bạn muốn làm việc với các phần tử "hiện tại" và "sắp tới", bạn có thể có các trình vòng lặp riêng cho cả hai. Hoặc nhiều luồng kéo từ một danh sách lớn: mỗi luồng có thể có trình vòng lặp riêng để duyệt qua tất cả các mục. Xem câu trả lời của @ Raymond@ glglgl ở trên.

Hãy tưởng tượng những gì bạn có thể làm:

class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

Ghi chú:

  • Tôi sẽ nhắc lại lần nữa: iterator không lặp lại được . Iterator không thể được sử dụng như một "nguồn" trong forvòng lặp. Những gì forvòng lặp chủ yếu cần là __iter__() (mà trả lại một cái gì đó với next()).

  • Tất nhiên, forkhông phải là vòng lặp duy nhất, vì vậy, ở trên cũng áp dụng cho một số cấu trúc khác ( while...).

  • Iterator next()có thể ném StopIteration để dừng lặp. Mặc dù vậy, nó không phải lặp đi lặp lại hoặc sử dụng các phương tiện khác.

  • Trong "quá trình suy nghĩ" ở trên, _ikhông thực sự tồn tại. Tôi đã tạo nên cái tên đó.

  • next()Bây giờ phải có một thay đổi nhỏ trong phương thức Python 3.x: (không phải là tích hợp sẵn) __next__(). Vâng, nó đáng lẽ phải như thế suốt.

  • Bạn cũng có thể nghĩ về nó như thế này: iterable có dữ liệu, iterator kéo mục tiếp theo

Tuyên bố miễn trừ trách nhiệm: Tôi không phải là nhà phát triển của bất kỳ trình thông dịch Python nào, vì vậy tôi không thực sự biết trình thông dịch "nghĩ gì". Những suy ngẫm ở trên chỉ là minh chứng cho cách tôi hiểu chủ đề từ những giải thích, thí nghiệm và trải nghiệm thực tế khác của một người mới chơi Python.


1
Điều này thật tuyệt - nhưng tôi vẫn hơi bối rối. Tôi nghĩ hộp màu vàng của bạn đang nói rằng một forvòng lặp cần một vòng lặp ("Hãy nhìn, một vòng lặp for. Trông giống như một công việc cho một vòng lặp ... Hãy lấy một vòng lặp."). Nhưng sau đó bạn nói trong phần ghi chú ở cuối rằng "Iterator có thể được sử dụng làm nguồn trong một forvòng lặp" ...?
Đua nòng nọc

Tại sao bạn chỉ đặt passmã cho các nextđịnh nghĩa đó? Tôi sẽ cho rằng bạn chỉ có nghĩa là ai đó phải thực hiện một cách để có được cái tiếp theo, vì tiếp theo phải trả lại một cái gì đó.
nealmcb

@nealmcb Vâng, tôi nghĩ đó là những gì tôi muốn nói. (Đó là những gì passdành cho , sau tất cả.)
Alois Mahdal

@AloisMahdal Ahh, tôi chưa thấy sử dụng trước đó. Khi tôi nhìn thấy pass, tôi nghĩ rằng nó là có lý do cú pháp. Tôi chỉ chạy qua các câu trả lời tại đối tượng dấu chấm lửng khá thú vị: bạn có thể sử dụng ...để chỉ ra khối "việc cần làm sau". NotImplementedcũng có sẵn.
nealmcb

Trong khi tôi thích rằng bạn đang nhấn mạnh sự khác biệt giữa một trình vòng lặp và một vòng lặp, thì câu trả lời này mâu thuẫn với chính nó. Trước tiên, bạn viết, 'Trình lặp cũng chính chúng có thể lặp lại', (khớp với những gì được viết trong tài liệu Python ). Nhưng sau đó bạn viết: ' iterator is iterable . Iterator không thể được sử dụng như một "nguồn" trong forvòng lặp '. Tôi nhận được điểm của câu trả lời của bạn, và thích nó khác, nhưng tôi nghĩ nó sẽ có lợi từ việc sửa lỗi này.
Giàu

22

Một iterable là một đối tượng có một __iter__()phương thức. Nó có thể lặp đi lặp lại nhiều lần, chẳng hạn như list()s và tuple()s.

Một iterator là đối tượng lặp đi lặp lại. Nó được trả về bởi một __iter__()phương thức, trả về chính nó thông qua __iter__()phương thức riêng của nó và có một next()phương thức ( __next__()trong 3.x).

Lặp đi lặp lại là quá trình gọi sự tôn trọng này next(). __next__()cho đến khi nó tăng StopIteration.

Thí dụ:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1

Vì vậy, thực sự nó chỉ là một đối tượng đi qua container? điều này có hữu ích không?
thechrishaddad

Thường xuyên, nhưng không phải luôn luôn. Một trình tạo con trỏ, tệp hoặc cơ sở dữ liệu chỉ có thể được lặp lại một lần và do đó là các trình lặp riêng của chúng.
glglgl

Tôi đoán b2 không phải độc lập với b1? trong trường hợp đặc biệt này, nó độc lập, chắc chắn tôi có thể làm cho nó không độc lập mà còn hợp lệ Iterable.
Bin

@Bin Có. Như và Iteratorluôn luôn Iterablelà của riêng mình Iterator, hai cuộc gọi iter()không nhất thiết phải đưa ra hai Iterators độc lập .
glglgl

13

Đây là bảng cheat của tôi:

 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+

Trắc nghiệm: Bạn có thấy ...

  1. mỗi lần lặp là một lần lặp?
  2. một đối tượng container __iter__()Phương thức có thể được thực hiện như một trình tạo không?
  3. một iterable có một __next__phương thức không nhất thiết phải là một iterator?

Đáp án:

  1. Mỗi iterator phải có một __iter__phương thức. Đang có__iter__ đủ để là một lặp đi lặp lại. Do đó, mỗi iterator là một iterable.
  2. Khi __iter__được gọi, nó sẽ trả về một iterator ( return <iterator>trong sơ đồ trên). Gọi một trình tạo trả về một trình vòng lặp trình tạo là một kiểu trình vòng lặp.

    class Iterable1:
        def __iter__(self):
            # a method (which is a function defined inside a class body)
            # calling iter() converts iterable (tuple) to iterator
            return iter((1,2,3))
    
    class Iterable2:
        def __iter__(self):
            # a generator
            for i in (1, 2, 3):
                yield i
    
    class Iterable3:
        def __iter__(self):
            # with PEP 380 syntax
            yield from (1, 2, 3)
    
    # passes
    assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
  3. Đây là một ví dụ:

    class MyIterable:
    
        def __init__(self):
            self.n = 0
    
        def __getitem__(self, index: int):
            return (1, 2, 3)[index]
    
        def __next__(self):
            n = self.n = self.n + 1
            if n > 3:
                raise StopIteration
            return n
    
    # if you can iter it without raising a TypeError, then it's an iterable.
    iter(MyIterable())
    
    # but obviously `MyIterable()` is not an iterator since it does not have
    # an `__iter__` method.
    from collections.abc import Iterator
    assert isinstance(MyIterable(), Iterator)  # AssertionError

1
Trong bài kiểm tra, tôi chỉ hiểu điểm đầu tiên. tức là iterator trở thành một iterable vì nó có __iter__phương thức. Bạn có thể giải thích rõ hơn về điểm 2 và 3 bằng cách chỉnh sửa câu trả lời này không
AnV

@AnV: Theo như tôi hiểu: re 2.: Trả __iter__()về một iterator. Một trình tạo là một trình vòng lặp, vì vậy nó có thể được sử dụng cho mục đích này. re 3.: Tôi chỉ có thể đoán ở đây, nhưng tôi nghĩ rằng nếu __iter__()bị thiếu hoặc không quay trở lại self, đó không phải là một trình vòng lặp, bởi vì một trình vòng lặp __iter__()phải quay trở lại self.
glglgl

10

Tôi không biết nó có giúp được ai không nhưng tôi luôn thích hình dung các khái niệm trong đầu để hiểu rõ hơn về chúng. Vì vậy, khi tôi có một đứa con trai nhỏ, tôi hình dung khái niệm iterable / iterator bằng gạch và giấy trắng.

Giả sử chúng tôi ở trong phòng tối và trên sàn nhà chúng tôi có gạch cho con trai tôi. Gạch có kích thước, màu sắc khác nhau, không quan trọng bây giờ. Giả sử chúng ta có 5 viên gạch như thế. 5 viên gạch đó có thể được mô tả như một đối tượng - giả sử bộ gạch . Chúng ta có thể làm nhiều thứ với bộ gạch này - có thể lấy một cái rồi lấy thứ hai rồi thứ ba, có thể thay đổi vị trí của viên gạch, đặt viên gạch đầu tiên lên trên cái thứ hai. Chúng ta có thể làm nhiều thứ với những thứ đó. Do đó, bộ công cụ gạch này là một đối tượng hoặc trình tự lặp lại khi chúng ta có thể đi qua từng viên gạch và làm một cái gì đó với nó. Chúng tôi chỉ có thể làm điều đó như con trai nhỏ của tôi - chúng tôi có thể chơi với một viên gạch cùng một lúc . Vì vậy, một lần nữa tôi tưởng tượng mình bộ gạch này là mộtiterable .

Bây giờ hãy nhớ rằng chúng ta đang ở trong phòng tối. Hoặc gần như tối. Vấn đề là chúng ta không nhìn rõ những viên gạch đó, màu gì, hình dạng gì, v.v. Vì vậy, ngay cả khi chúng ta muốn làm gì đó với chúng - hay lặp đi lặp lại qua chúng - chúng ta không thực sự biết nó là gì và vì nó là như thế nào quá tối.

Những gì chúng ta có thể làm là ở gần viên gạch đầu tiên - như là một yếu tố của bộ gạch - chúng ta có thể đặt một mảnh giấy huỳnh quang trắng để chúng ta thấy vị trí của phần tử gạch đầu tiên. Và mỗi lần chúng tôi lấy một viên gạch từ một bộ dụng cụ, chúng tôi thay thế mảnh giấy trắng thành một viên gạch tiếp theo để có thể nhìn thấy nó trong căn phòng tối. Mảnh giấy trắng này không gì khác hơn là một vòng lặp . Nó là một đối tượng là tốt . Nhưng một đối tượng với những gì chúng ta có thể làm việc và chơi với các yếu tố của đối tượng lặp lại của chúng ta - bộ gạch.

Nhân tiện, điều đó giải thích cho sai lầm ban đầu của tôi khi tôi đã thử những điều sau trong IDLE và nhận được TypeError:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

Danh sách X ở đây là bộ gạch của chúng tôi nhưng KHÔNG phải là một mảnh giấy trắng. Tôi cần tìm một iterator trước:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

Không biết nếu nó giúp, nhưng nó đã giúp tôi. Nếu ai đó có thể xác nhận / hình dung chính xác khái niệm, tôi sẽ biết ơn. Nó sẽ giúp tôi tìm hiểu thêm.


6

Lặp lại : - một cái gì đó có thể lặp lại được lặp đi lặp lại; như các chuỗi như danh sách, chuỗi, vv Ngoài ra, nó có __getitem__phương thức hoặc __iter__phương thức. Bây giờ nếu chúng ta sử dụng iter()hàm trên đối tượng đó, chúng ta sẽ có một trình vòng lặp.

Iterator : - Khi chúng ta lấy đối tượng iterator từ iter()hàm; chúng ta gọi __next__()phương thức (trong python3) hoặc đơn giản next()(trong python2) để lấy các phần tử từng cái một. Lớp này hoặc thể hiện của lớp này được gọi là iterator.

Từ tài liệu: -

Việc sử dụng các trình lặp lặp lại và thống nhất Python. Đằng sau hậu trường, câu lệnh for gọi  iter() đối tượng container. Hàm trả về một đối tượng iterator xác định phương thức  __next__() truy cập các phần tử trong vùng chứa một lần. Khi không còn phần tử nào nữa,  __next__() sẽ xuất hiện ngoại lệ StopIteration để cho vòng lặp for chấm dứt. Bạn có thể gọi  __next__() phương thức bằng hàm  next() dựng sẵn; ví dụ này cho thấy tất cả hoạt động như thế nào:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

Ví dụ của một lớp: -

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s

4

Tôi không nghĩ rằng bạn có thể làm cho nó đơn giản hơn nhiều so với tài liệu , tuy nhiên tôi sẽ thử:

  • Lặp đi lặp lại là một cái gì đó có thể được lặp đi lặp lại . Trong thực tế, nó thường có nghĩa là một chuỗi, ví dụ như một cái gì đó có một khởi đầu và kết thúc và một số cách để đi qua tất cả các mục trong đó.
  • Bạn có thể nghĩ Iterator như một phương thức giả trợ giúp (hoặc thuộc tính giả) cung cấp (hoặc giữ) mục tiếp theo (hoặc đầu tiên) trong lần lặp . (Trong thực tế, nó chỉ là một đối tượng xác định phương thức next())

  • Lặp lại có lẽ được giải thích tốt nhất theo định nghĩa của Merriam-Webster của từ :

b: sự lặp lại của một chuỗi các hướng dẫn máy tính một số lần xác định hoặc cho đến khi một điều kiện được đáp ứng - so sánh đệ quy


3
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

vì thế,

  1. iterablelà một đối tượng có thể được lặp qua . ví dụ: danh sách, chuỗi, tuple, v.v.

  2. sử dụng iterhàm trên iterableđối tượng của chúng ta sẽ trả về một đối tượng iterator.

  3. bây giờ đối tượng iterator này có phương thức được đặt tên __next__(trong Python 3, hoặc chỉ nexttrong Python 2) mà bạn có thể truy cập từng phần tử của iterable.

vì vậy, ĐẦU RA CỦA MÃ TRÊN SILL ĐƯỢC:

1

2


3

Lặp lại có một __iter__phương thức khởi tạo một trình vòng lặp mới mỗi lần.

Các trình vòng lặp thực hiện một __next__phương thức trả về các mục riêng lẻ và một __iter__phương thức trả về self.

Do đó, các trình vòng lặp cũng có thể lặp lại, nhưng các trình vòng lặp không phải là các trình vòng lặp.

Luciano Ramalho, Python thông thạo.


2

Trước khi làm việc với iterables và iterator, yếu tố chính quyết định iterable và iterator là chuỗi

Trình tự: Trình tự là tập hợp dữ liệu

Iterable: Iterable là đối tượng kiểu trình tự hỗ trợ __iter__phương thức.

Phương thức lặp: Phương thức Iter lấy chuỗi làm đầu vào và tạo một đối tượng được gọi là iterator

Iterator: Iterator là đối tượng gọi phương thức tiếp theo và chuyển qua chuỗi. Khi gọi phương thức tiếp theo, nó trả về đối tượng mà nó hiện đang đi qua.

thí dụ:

x=[1,2,3,4]

x là một chuỗi bao gồm tập hợp dữ liệu

y=iter(x)

Khi gọi iter(x)nó chỉ trả về một iterator khi đối tượng x có phương thức iter nếu không nó sẽ đưa ra một ngoại lệ. Nếu nó trả về iterator thì y được gán như thế này:

y=[1,2,3,4]

Vì y là một iterator do đó nó hỗ trợ next()phương thức

Khi gọi phương thức tiếp theo, nó trả về từng phần tử của danh sách một.

Sau khi trả về phần tử cuối cùng của chuỗi nếu chúng ta gọi lại phương thức tiếp theo, nó sẽ xuất hiện lỗi StopIteration

thí dụ:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration

Chỉ là một quan sát: y = iter (x) không chính xác y = [1,2,3,4] vì y bây giờ là một đối tượng lặp. Có lẽ bạn nên thêm một nhận xét để làm rõ đó không phải là một danh sách mà là một đối tượng lặp hoặc thay đổi biểu diễn.
coelhudo

-6

Trong Python mọi thứ đều là một đối tượng. Khi một đối tượng được cho là có thể lặp lại, điều đó có nghĩa là bạn có thể bước qua (tức là lặp lại) đối tượng như một bộ sưu tập.

Mảng ví dụ là lặp đi lặp lại. Bạn có thể bước qua chúng bằng một vòng lặp for và đi từ chỉ số 0 đến chỉ số n, n là độ dài của đối tượng mảng trừ đi 1.

Từ điển (cặp khóa / giá trị, còn được gọi là mảng kết hợp) cũng có thể lặp lại. Bạn có thể bước qua các phím của họ.

Rõ ràng các đối tượng không phải là bộ sưu tập không thể lặp lại. Ví dụ, một đối tượng bool chỉ có một giá trị, Đúng hoặc Sai. Nó không thể lặp lại được (sẽ không có nghĩa là nó là một đối tượng có thể lặp lại).

Đọc thêm. http://www.lepus.org.uk/ref/compmate/Iterator.xml


6
Các đối tượng không phải là bộ sưu tập không lặp lại thường không đúng. Để chỉ đưa ra một vài ví dụ, các trình tạo có thể lặp lại nhưng không phải là các bộ sưu tập và các đối tượng của trình lặp được tạo bằng cách gọi iter()các kiểu bộ sưu tập tiêu chuẩn là lặp lại nhưng bản thân chúng không phải là các bộ sưu tập.
Đánh dấu Amery
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.