2014-02-23 25 views
2

随着iter(),我可以这样做:iter()内置什么?

>>> listWalker = iter ([23, 47, 'hike']) 
>>> for x in listWalker: print x, 

但我能做到这一点呢:

>>> listWalker = [23, 47, 'hike'] 
>>> for x in listWalker: print x, 

它增加什么价值?

+0

有一个很好的例子,使用'iter' [这里](http://stackoverflow.com/questions/2233204/how-does-zipitersn-work-in-python)。 – GWW

+0

相关:[为什么一个Python Iterator需要一个简单地返回自我的iter方法?](http://stackoverflow.com/questions/21343327/why-does-a-python-iterator-need-an-iter-method- that-simply-returns-self) –

+0

事实上,这个“相关”的问题有一个顶部答案的答案。我倾向于同意投票结束。 –

回答

0

当你在一个变量上做一个for循环时,它隐式地调用你实际通过的iterable的__iter__方法。
你总是使用iter()是当你循环列表,元组......和每一个迭代时的某种方式。

我觉得这种提取物的字节码可以说服你:

>>> 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 


但是,iterables还允许你在Python一些其他的东西,如使用的 next()走进一个迭代,或提高 StopIteration exception。如果您正在处理不同的对象类型并且您想要应用通用算法,那将会非常有用。

+0

Downvoter,请解释一下? –

4

iter的要点是,它允许您从一个可迭代对象中获取迭代器并自行使用它,以实现自己的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) 
+0

+1非常好,*实用*创建同一个迭代器的多个迭代器的例子。 – chepner

5

除了使用iter明确地获得一个迭代器实现该__iter__方法的对象,有一个鲜为人知的双参数形式iter,它使迭代器重复调用一个函数,直到它返回给定的sentinel值。

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__方法。

+1

+1优秀的答案,涵盖了“iter”的“正常”使用和双参数形式。您可能希望更精确地指出迭代器**可以是它所迭代的对象的不同对象。许多对象,特别是文件对象,还有迭代器本身,都是它们自己的迭代器。 – user4815162342

0

the docs

ITER(O [,定点])

[...]如果没有第二个参数,邻必须是支持 迭代协议(该__iter__()一个集合对象方法),或者它必须支持 序列协议(__getitem__()方法,整数参数 从0开始)。如果它不支持这两种协议,则会引发 TypeError。 [...]

所以它从一个对象构造一个迭代器。正如你所说,这是在循环和理解中自动完成的,但有些时候你想获得一个迭代器并直接处理它。只要把它放在你脑海的后面,直到你需要它为止。

当使用第二个参数:

如果第二个参数,前哨,给定,然后按o必须是一个可调用对象。 在这种情况下创建的迭代器将为每个调用 的next()方法调用o而不带参数;如果返回的值等于哨兵,则 将会提高StopIteration,否则将返回该值。

这是传统风格的功能,如file.read(bufsize)具有反复调用,直到它返回""许多有用的东西,但尤其如此。可以将其转换为iter(lambda : file.read(bufsize), "")的迭代器。干净又干净!

相关问题