Python es un lenguaje especial en términos de iteraciones y su implementación, en este artículo analizaremos en detalle el dispositivo de los objetos iterables y el bucle notorio for
.
Características que a menudo puede encontrar en las actividades diarias
1. Usando el generador dos veces
>>> 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)
[]
Como vemos en este ejemplo, el uso de la variable squared_numbers
dos veces dio el resultado esperado en el primer caso, y para personas que no están lo suficientemente familiarizadas con Python, el resultado inesperado en el segundo.
2. Comprobación de la entrada del elemento en el generador
Tomemos las mismas variables:
>>> 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
.
:
- ,
iter
TypeError
— . - ,
next
TypeError
— . - ,
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.
Cualquier objeto iterable implementa un protocolo iterador. Comprender este protocolo es la clave para comprender cualquier iteración en Python.