使用iter()
,我可以做到这一点:
>>> listWalker = iter ( [23, 47, 'hike'] )
>>> for x in listWalker: print x,
但我仍然可以做到这一点:
>>> listWalker = [23, 47, 'hike']
>>> for x in listWalker: print x,
它能增加哪些价值?
使用iter()
,我可以做到这一点:
>>> listWalker = iter ( [23, 47, 'hike'] )
>>> for x in listWalker: print x,
>>> listWalker = [23, 47, 'hike']
>>> for x in listWalker: print x,
它能增加哪些价值?
iter
来显式地获取实现了 __iter__
方法的对象的迭代器外,还有一种不太常见的 iter
的两个参数形式,它可以创建一个迭代器,该迭代器反复调用一个函数,直到函数返回给定的标记值。 for line in iter(f.readline, 'EOF'):
print line
上述代码将调用f.read
(例如,对于一个打开的文件句柄f
),直到它读取到由字符串EOF
组成的一行。这与编写以下代码大致相同:
for line in f:
if line == "EOF":
break
print line
此外,迭代器可以是与其迭代的对象不同的独立对象。这对于list
类型来说是正确的。这意味着您可以创建两个迭代器,它们都可以 独立 地迭代相同的对象。
itr1 = iter(mylist)
itr2 = iter(mylist)
x = next(itr1) # First item of mylist
y = next(itr1) # Second item of my list
z = next(itr2) # First item of mylist, not the third
文件句柄本身充当它们自己的迭代器:
>>> f = open('.bashrc')
>>> id(f)
4454569712
>>> id(iter(f))
4454569712
通常情况下,iter
返回的对象取决于对象类型实现的__iter__
方法。
iter
的“正常”用法和两个参数形式。你可能需要更准确地说明迭代器可以是与其迭代的对象不同的独立对象。许多对象,尤其是文件对象,以及迭代器本身,都是它们自己的迭代器。 - user4815162342iter
的目的是允许您从可迭代对象中获取迭代器并自己使用它,无论是实现自己的for
循环变体还是在多个循环之间维护迭代状态。以下是一个简单的示例:
it = iter(['HEADER', 0, 1, 2, 3]) # coming from CSV or such
title = it.next()
for item in it:
# process item
...
iter
的更高级用法是通过这种分组惯用法提供的:
def in_groups(iterable, n):
"""Yield element from iterables grouped in tuples of size n."""
it = iter(iterable)
iters = [it] * n
return zip(*iters)
>>> def a():
... for x in [1,2,3]:
... print x
...
>>> import dis
>>> dis.dis(a)
2 0 SETUP_LOOP 28 (to 31)
3 LOAD_CONST 1 (1)
6 LOAD_CONST 2 (2)
9 LOAD_CONST 3 (3)
12 BUILD_LIST 3
15 GET_ITER # <--- get iter is important here
>> 16 FOR_ITER 11 (to 30)
19 STORE_FAST 0 (x)
3 22 LOAD_FAST 0 (x)
25 PRINT_ITEM
26 PRINT_NEWLINE
27 JUMP_ABSOLUTE 16
>> 30 POP_BLOCK
>> 31 LOAD_CONST 0 (None)
34 RETURN_VALUE
next()
来遍历一个可迭代对象,或者引发一个StopIteration
异常。如果你正在处理不同的对象类型,并且想应用一个通用的算法,这可能会很有用。从文档中:
iter(o[, sentinel])
[...] 如果没有第二个参数,o必须是一个支持迭代协议(
__iter__()
方法)的集合对象,或者它必须支持序列协议(__getitem__()
方法以0开始的整数参数)。如果它不支持这两个协议,则会引发TypeError异常。 [...]
因此,它从一个对象构造一个迭代器。
正如你所说,在循环和推导式中,这是自动完成的,但有时你想获取一个迭代器并直接处理它。只需将其记在脑后,直到你需要它。
当使用第二个参数时:
这对于许多事情都很有用,特别是对于像如果给定了第二个参数sentinel,那么o必须是一个可调用对象。 在这种情况下创建的迭代器将在每次调用其next()方法时无参数地调用o; 如果返回的值等于sentinel,则会引发StopIteration异常,否则将返回该值。
file.read(bufsize)
这样的传统风格函数尤其如此,它必须重复调用直到返回""
。可以使用iter(lambda : file.read(bufsize), "")
将其转换为迭代器。简洁明了!
iter
的示例:链接。 - GWWiter(some_iterator)
起作用。而这个问题问的是为什么存在一个iter
函数(当for
本来就能完成任务时)。这两个问题并不相同。 - user4815162342iter
的功能,但没有解释为什么需要这样做的意义所在。(它还解释了为什么iter
需要__iter__
,这与这个问题更无关。) - user4815162342