就迭代及其实现而言,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. :)
, :
- .
- next.
- ' '.
- , 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, .
.
:
- iter.
- next.
- , StopIteration.
:
- , iterTypeError— .
- , nextTypeError— .
- , iter— .
:
- "" (en. lazy). , - , , . 
 
- , 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中任何迭代的关键。