iter() 对列表做了什么?
What does iter() do to list?
我有这个代码:
a = ['animal', 'dog', 'car', 'bmw', 'color', 'blue']
a_iter = iter(a)
print(a)
print(a_iter)
print(dict(zip(a,a)))
print(dict(zip(a_iter,a_iter)))
输出为:
['animal', 'dog', 'car', 'bmw', 'color', 'blue']
<list_iterator object at 0x7f2d98b756d8>
{'dog': 'dog', 'car': 'car', 'animal': 'animal', 'color': 'color', 'blue': 'blue', 'bmw': 'bmw'}
{'car': 'bmw', 'color': 'blue', 'animal': 'dog'}
我不明白为什么 zip 在 a_iter
和 a
下的工作方式不同。 iter()
有什么作用,list是可迭代的,为什么要用iter()
呢?有人可以用一些很好的例子向我解释吗?我用谷歌搜索了它,但我还是不明白。
iter()
对列表没有任何作用; list
对象有一个 __iter__
方法,iter()
使用它来生成迭代器对象。该对象具有对原始列表和索引的引用;每次在迭代器中请求下一个值时,都会检索并返回当前索引处的值,并且索引会递增。
您可以使用 next()
函数从迭代器中获取下一个值:
>>> a = ['animal', 'dog', 'car', 'bmw', 'color', 'blue']
>>> a_iter = iter(a)
>>> next(a_iter) # get the next value
'animal'
>>> next(a_iter) # get the next value
'dog'
请注意如何再次调用 next()
为您提供新值。您可以这样做,直到迭代器完成:
>>> three_more = next(a_iter), next(a_iter), next(a_iter)
>>> next(a_iter) # last one
'blue'
>>> next(a_iter) # nothing left
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
列表迭代器对象保留原始列表对象;更改列表对象将反映在 next()
:
上生成的迭代器值中
>>> b = ['foo', 'bar']
>>> b_iter = iter(b)
>>> next(b_iter)
'foo'
>>> b[1] = 'spam'
>>> b
['foo', 'spam']
>>> next(b_iter)
'spam'
zip()
要求每个参数中的下一个值,假定为 iterables; zip()
对他们全部调用 iter()
。对于 a_iter
、iter(a_iter)
returns 等迭代器对象,迭代器本身(毕竟它已经是一个迭代器):
>>> iter(a_iter)
<list_iterator object at 0x10e7b6a20>
>>> iter(a_iter) is a_iter
True
由于 a_iter
将从原始列表中按顺序产生值,这意味着您在字典中得到成对的元素,因为 zip()
有 两个引用同一个对象;您实际上创建了 (next(a_iter), next(a_iter))
作为 zip()
的迭代器步长值。另一方面,如果您传入对 a
的两个引用,zip()
将调用 iter()
两次 ,创建 两个独立的迭代器对象,每个都有自己的索引来跟踪。
让我们详细看一下。请注意 zip()
也 生成一个迭代器对象,因此我们可以验证在 zip()
上调用 next()
反过来会导致 a_iter
步进转发两次:
>>> a_iter = iter(a)
>>> a_iter_zip = zip(a_iter, a_iter)
>>> a_iter_zip # a zip object is an iterator too
<zip object at 0x10e7ba8c8>
>>> next(a_iter_zip) # get next value of a_iter, together with the next value of a_iter
('animal', 'dog')
>>> next(a_iter) # the a-list iterator was advanced, so now we get 'car'
'car'
>>> next(a_iter_zip) # now a_iter is at bmw, so we get bmw and color
('bmw', 'color')
迭代器是独立的对象,它们都有自己的索引:
>>> a_iter1 = iter(a)
>>> a_iter2 = iter(a) # different iterator from a_iter1
>>> next(a_iter1), next(a_iter1) # what zip() does
('animal', 'dog')
>>> next(a_iter2), next(a_iter2) # iter2 is independent
('animal', 'dog')
所以当您使用 zip(a, a)
时,真正发生的是 zip()
调用 iter(a)
两次,创建两个新的迭代器,并且都用于创建输出:
>>> a_iter1 = iter(a)
>>> a_iter2 = iter(a)
>>> a_iter_1_and_2_zip = zip(a_iter1, a_iter2)
>>> next(a_iter_1_and_2_zip) # values from a_iter1 and a_iter2
('animal', 'animal')
>>> next(a_iter_1_and_2_zip) # moving in lockstep
('dog', 'dog')
>>> next(a_iter1) # moving one of these two one step along, to 'car'
'car'
>>> next(a_iter_1_and_2_zip) # so a_iter1 is one step ahead!
('bmw', 'car')
>>> next(a_iter1) # another extra step
'color'
>>> next(a_iter_1_and_2_zip) # so a_iter1 is two steps ahead!
('blue', 'bmw')
iter() 函数 return 一个迭代器实例,我们可以在其上迭代以通过 one.It 获取所有值 1 是内存高效函数,因为它仅存储当前元素值。
iter(l)
returns an iterator object for l
. Together with next(i)
可用于迭代l
.
的元素
代码:
for x in l: print(x)
等同于显式使用迭代器的代码:
i = iter(l)
while True:
try:
x = next(i)
print(x)
except StopIteration:
break
注意迭代器也可以用for循环遍历:
i = iter(l)
for x in i:
print(x)
zip(a,b)
一次消耗a
、b
中的一个元素。
当 zip 的参数是一个序列时,它会为它创建自己的迭代器。
当参数是迭代器时,它只会消耗其中的元素。
当两个参数都是相同的迭代器时,zip 的每次迭代都会为第一个参数消耗迭代器的一个元素,为第二个参数消耗一个元素。
>>> a = [1,2,3,4]
>>> b = [10,20,30,40]
>>> list(zip(a, b)) # zip two lists
[(1, 10), (2, 20), (3, 30), (4, 40)]
>>> list(zip(a, a)) # zip a list with itself
[(1, 1), (2, 2), (3, 3), (4, 4)]
>>> i1 = iter(a)
>>> i2 = iter(a)
>>> list(zip(i1, i2)) # same as above, but with iterators
[(1, 1), (2, 2), (3, 3), (4, 4)]
>>> i = iter(a)
>>> list(zip(i, i)) # same as above, but with the same iterator
[(1, 2), (3, 4)]
我有这个代码:
a = ['animal', 'dog', 'car', 'bmw', 'color', 'blue']
a_iter = iter(a)
print(a)
print(a_iter)
print(dict(zip(a,a)))
print(dict(zip(a_iter,a_iter)))
输出为:
['animal', 'dog', 'car', 'bmw', 'color', 'blue']
<list_iterator object at 0x7f2d98b756d8>
{'dog': 'dog', 'car': 'car', 'animal': 'animal', 'color': 'color', 'blue': 'blue', 'bmw': 'bmw'}
{'car': 'bmw', 'color': 'blue', 'animal': 'dog'}
我不明白为什么 zip 在 a_iter
和 a
下的工作方式不同。 iter()
有什么作用,list是可迭代的,为什么要用iter()
呢?有人可以用一些很好的例子向我解释吗?我用谷歌搜索了它,但我还是不明白。
iter()
对列表没有任何作用; list
对象有一个 __iter__
方法,iter()
使用它来生成迭代器对象。该对象具有对原始列表和索引的引用;每次在迭代器中请求下一个值时,都会检索并返回当前索引处的值,并且索引会递增。
您可以使用 next()
函数从迭代器中获取下一个值:
>>> a = ['animal', 'dog', 'car', 'bmw', 'color', 'blue']
>>> a_iter = iter(a)
>>> next(a_iter) # get the next value
'animal'
>>> next(a_iter) # get the next value
'dog'
请注意如何再次调用 next()
为您提供新值。您可以这样做,直到迭代器完成:
>>> three_more = next(a_iter), next(a_iter), next(a_iter)
>>> next(a_iter) # last one
'blue'
>>> next(a_iter) # nothing left
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
列表迭代器对象保留原始列表对象;更改列表对象将反映在 next()
:
>>> b = ['foo', 'bar']
>>> b_iter = iter(b)
>>> next(b_iter)
'foo'
>>> b[1] = 'spam'
>>> b
['foo', 'spam']
>>> next(b_iter)
'spam'
zip()
要求每个参数中的下一个值,假定为 iterables; zip()
对他们全部调用 iter()
。对于 a_iter
、iter(a_iter)
returns 等迭代器对象,迭代器本身(毕竟它已经是一个迭代器):
>>> iter(a_iter)
<list_iterator object at 0x10e7b6a20>
>>> iter(a_iter) is a_iter
True
由于 a_iter
将从原始列表中按顺序产生值,这意味着您在字典中得到成对的元素,因为 zip()
有 两个引用同一个对象;您实际上创建了 (next(a_iter), next(a_iter))
作为 zip()
的迭代器步长值。另一方面,如果您传入对 a
的两个引用,zip()
将调用 iter()
两次 ,创建 两个独立的迭代器对象,每个都有自己的索引来跟踪。
让我们详细看一下。请注意 zip()
也 生成一个迭代器对象,因此我们可以验证在 zip()
上调用 next()
反过来会导致 a_iter
步进转发两次:
>>> a_iter = iter(a)
>>> a_iter_zip = zip(a_iter, a_iter)
>>> a_iter_zip # a zip object is an iterator too
<zip object at 0x10e7ba8c8>
>>> next(a_iter_zip) # get next value of a_iter, together with the next value of a_iter
('animal', 'dog')
>>> next(a_iter) # the a-list iterator was advanced, so now we get 'car'
'car'
>>> next(a_iter_zip) # now a_iter is at bmw, so we get bmw and color
('bmw', 'color')
迭代器是独立的对象,它们都有自己的索引:
>>> a_iter1 = iter(a)
>>> a_iter2 = iter(a) # different iterator from a_iter1
>>> next(a_iter1), next(a_iter1) # what zip() does
('animal', 'dog')
>>> next(a_iter2), next(a_iter2) # iter2 is independent
('animal', 'dog')
所以当您使用 zip(a, a)
时,真正发生的是 zip()
调用 iter(a)
两次,创建两个新的迭代器,并且都用于创建输出:
>>> a_iter1 = iter(a)
>>> a_iter2 = iter(a)
>>> a_iter_1_and_2_zip = zip(a_iter1, a_iter2)
>>> next(a_iter_1_and_2_zip) # values from a_iter1 and a_iter2
('animal', 'animal')
>>> next(a_iter_1_and_2_zip) # moving in lockstep
('dog', 'dog')
>>> next(a_iter1) # moving one of these two one step along, to 'car'
'car'
>>> next(a_iter_1_and_2_zip) # so a_iter1 is one step ahead!
('bmw', 'car')
>>> next(a_iter1) # another extra step
'color'
>>> next(a_iter_1_and_2_zip) # so a_iter1 is two steps ahead!
('blue', 'bmw')
iter() 函数 return 一个迭代器实例,我们可以在其上迭代以通过 one.It 获取所有值 1 是内存高效函数,因为它仅存储当前元素值。
iter(l)
returns an iterator object for l
. Together with next(i)
可用于迭代l
.
代码:
for x in l: print(x)
等同于显式使用迭代器的代码:
i = iter(l)
while True:
try:
x = next(i)
print(x)
except StopIteration:
break
注意迭代器也可以用for循环遍历:
i = iter(l)
for x in i:
print(x)
zip(a,b)
一次消耗a
、b
中的一个元素。
当 zip 的参数是一个序列时,它会为它创建自己的迭代器。
当参数是迭代器时,它只会消耗其中的元素。
当两个参数都是相同的迭代器时,zip 的每次迭代都会为第一个参数消耗迭代器的一个元素,为第二个参数消耗一个元素。
>>> a = [1,2,3,4]
>>> b = [10,20,30,40]
>>> list(zip(a, b)) # zip two lists
[(1, 10), (2, 20), (3, 30), (4, 40)]
>>> list(zip(a, a)) # zip a list with itself
[(1, 1), (2, 2), (3, 3), (4, 4)]
>>> i1 = iter(a)
>>> i2 = iter(a)
>>> list(zip(i1, i2)) # same as above, but with iterators
[(1, 1), (2, 2), (3, 3), (4, 4)]
>>> i = iter(a)
>>> list(zip(i, i)) # same as above, but with the same iterator
[(1, 2), (3, 4)]