了解Python中的迭代器

就迭代及其实现而言,Python是一种特殊的语言,在本文中,我们将详细分析可迭代对象的设备和臭名昭著的循环for


您在日常活动中可能经常遇到的功能


1.两次使用发电机


>>> numbers = [1,2,3,4,5]

>>> squared_numbers = (number**2 for number in numbers)

>>> list(squared_numbers)
[1, 4, 9, 16, 25]

>>> list(squared_numbers)
[]

正如我们在本例中看到的,squared_numbers在第一种情况下,两次使用变量可以得到预期的结果,而对于不熟悉Python的人,在第二种情况下可以得到意外的结果。


2.检查元素在生成器中的输入


让我们采用相同的变量:


>>> numbers = [1,2,3,4,5]
>>> squared_numbers = (number**2 for number in numbers)

, , :


>>> 4 in squared_numbers
True
>>> 4 in squared_numbers
False

.


3.


:


>>> fruits_amount = {'apples': 2, 'bananas': 5}

:


>>> x, y = fruits_amount

, , Python, " ":


>>> x
'apples'
>>> y
'bananas'


-, , , , .


, : , .


>>> numbers = [1,2,3,4,5]
>>> letters = ('a','b','c')
>>> characters = 'habristhebestsiteever'
>>> numbers[1]
2
>>> letters[2]
'c'
>>> characters[11]
's'
>>> characters[0:4]
'habr'

, , , , , , : for, , — .


# Can't be indexed
>>> unordered_numbers = {1,2,3}
>>> unordered_numbers[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable

>>> users = {'males': 23, 'females': 32}
>>> users[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 1

# Can be used as sequence
>>> [number**2 for number in unordered_numbers]
[1, 4, 9]
>>>
>>> for user in users:
...     print(user)
... 
males
females

for Python


, for, Python, , . for...each, for...of.


, for while, , :


>>> list_of_numbers = [1,2,3]
>>> index = 0
>>> while index < len(list_of_numbers):
...     print(list_of_numbers[index])
...     index += 1
... 
1
2
3

, , :


>>> set_of_numbers = {1,2,3}
>>> index = 0 
>>> while index < len(set_of_numbers):
...     print(set_of_numbers[index])
...     index += 1
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'set' object is not subscriptable

index, enumerate:


>>> set_of_numbers = {1,2,3}
>>> for index, number in enumerate(set_of_numbers):
...     print(number, index)
... 
1 0
2 1
3 2

for


, for . .


— , , , :)
.


iter:


>>> set_of_numbers = {1,2,3}
>>> list_of_numbers = [1,2,3]
>>> string_of_numbers = '123'
>>> 
>>> iter(set_of_numbers)
<set_iterator object at 0x7fb192fa0480>
>>> iter(list_of_numbers)
<list_iterator object at 0x7fb193030780>
>>> iter(string_of_numbers)
<str_iterator object at 0x7fb19303d320>

, , next.


>>> set_of_numbers = {1,2,3}
>>> 
>>> numbers_iterator = iter(set_of_numbers)
>>> next(numbers_iterator)
1
>>> next(numbers_iterator)
2

, . , next StopIteration.


>>> next(numbers_iterator)
3
>>> next(numbers_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

-, , : next.
StopIteration, .


for while


, for, for. :)


, :


  1. .
  2. next.
  3. ' '.
  4. , StopIteration.

def for_loop(iterable, loop_body_func):
    iterator = iter(iterable)
    next_element_exist = True
    while next_element_exist:
        try:
            element_from_iterator = next(iterator)
        except StopIteration:
            next_element_exist = False
        else:
            loop_body_func(element_from_iterator)

, try-else. . , , .


.
, — , Python.
iter next . . for . "" :


coordinates = [1,2,3]
x, y, z = coordinates

numbers = [1,2,3,4,5]
a,b, *rest = numbers

print(*numbers)


:


>>> def custom_range(number):
...     index = 0 
...     while index < number:
...             yield index
...             index += 1
... 
>>> range_of_four = custom_range(4)
>>> next(range_of_four)
0
>>> next(range_of_four)
1
>>> next(range_of_four)
2
>>> next(range_of_four)
3
>>> next(range_of_four)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

, iter ,


>>> numbers = [1,2,3,4,5]
>>> iter1 = iter(numbers)
>>> iter2 = iter(iter1)
>>> next(iter1)
1
>>> next(iter2)
2
>>> iter1 is iter2
True

.


— -, .
iter, .


.



:


  1. iter .
  2. next.
  3. , StopIteration.

:


  1. , iter TypeError — .
  2. , next TypeError — .
  3. , iter — .

:


  1. "" (en. lazy). , - , , .


  2. , CPU, .




Python.
, — .
.


, , enumerate:


>>> numbers = [1,2,3]
>>> enumerate_var = enumerate(numbers)
>>> enumerate_var
<enumerate object at 0x7ff975dfdd80>
>>> next(enumerate_var)
(0, 1)

zip:


>>> letters = ['a','b','c']
>>> z = zip(letters, numbers)
>>> z
<zip object at 0x7ff975e00588>
>>> next(z)
('a', 1)

open:


>>> f = open('foo.txt')
>>> next(f)
'bar\n'
>>> next(f)
'baz\n'
>>> 

Python , , , , next. , "" .



, , , .


, , , , :)


class InfiniteSquaring:
"""        ."""
    def __init__(self, initial_number):
        #    
        self.number_to_square = initial_number

    def __next__(self):
        #       
        self.number_to_square = self.number_to_square ** 2
        return self.number_to_square

    def __iter__(self):
        """       iter   ,       ."""
        return self

>>> squaring_of_six = InfiniteSquaring(6)
>>> next(squaring_of_six)
36
>>> next(squaring_of_six)
1296
>>> next(squaring_of_six)
1679616
>>> next(squaring_of_six)
2821109907456
>>> next(squaring_of_six)
7958661109946400884391936
>>> #    ...

:


>>>iter(squaring_of_six) is squaring_of_six
True

.
, .
, .


,


1.


>>> numbers = [1,2,3,4,5]

>>> squared_numbers = (number**2 for number in numbers)

>>> list(squared_numbers)
[1, 4, 9, 16, 25]

>>> list(squared_numbers)
[]

, , — , , — . .


2.


>>> numbers = [1,2,3,4,5]
>>> squared_numbers = (number**2 for number in numbers)

, :


>>> 4 in squared_numbers
True
>>> 4 in squared_numbers
False

, 1 , , , , . :


>>> 4 in squared_numbers
True
>>> list(squared_numbers)
[9, 16, 25]
>>> list(squared_numbers)
[]

, , , . , , .


3.


for, :


>>> fruits_amount = {'apples': 2, 'bananas': 5}

>>> for fruit_name in fruits_amount:
...     print(fruit_name)
... 
apples
bananas

, :


>>> x, y = fruits_amount
>>> x
'apples'
>>> y
'bananas'


— , — .


— Python.


任何可迭代对象都实现迭代器协议。了解此协议是了解Python中任何迭代的关键。


All Articles