iter()是如何工作的,它给出了“TypeError:iter(v,w):v必须是可调用的”

时间:2013-11-08 08:05:48

标签: python python-3.x iterator typeerror

此代码有什么问题?

l = [1,2,3,4,5,6]
for val in iter(l, 4):
    print (val)

返回

TypeError: iter(v, w): v must be callable

为什么 callable(list)返回 True callable(l)不会?

修改 这里应该首选什么方法:

  1. 手动休息
  2. 其他一百个

7 个答案:

答案 0 :(得分:6)

来自iter帮助:

  

ITER(...)
      iter(collection) - >迭代器
      iter(callable,sentinel) - >迭代器

Get an iterator from an object.  In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.

您正在混合iter函数的两个变体。第一个接受集合,第二个接受两个参数 - 函数和sentinel值。你试图传递集合的哨兵值,这是错误的。

简短说明:你可以从python的内置help函数中获得很多有趣的信息。只需输入python的控制台help(iter),您就可以获得文档了。

  

为什么callabe(list)返回true但是callable(l)不返回?

因为list是返回新列表对象的函数。函数是可调用的(这是函数的作用 - 它被调用),而这个函数返回的实例 - 新的列表对象 - 不是。

答案 1 :(得分:5)

当使用两个参数调用时,iter采用可调用值和标记值。它的行为就像它实现的那样:

def iter2args(f, sentinel):
    value = f()
    while value != sentinel:
        yield value
        value = f()

传递给f的内容必须是 callable ,这意味着您可以像函数一样调用它。 list builtin是一个type对象,您可以通过将其称为函数来创建新的列表实例:

>>> list('abcde')
['a', 'b', 'c', 'd', 'e']

您传入的列表l是一个现有的列表实例,不能像函数一样使用:

>>> l = [1,2,3,4,5,6]
>>> l(3)
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    l(3)
TypeError: 'list' object is not callable

因此,list类型对象和列表实例之间存在巨大而重要的差异,与iter一起使用时会显示这些差异。

要遍历列表直到到达哨兵,您可以使用itertools.takewhile

import itertools
for val in itertools.takewhile(l, lambda x: x!= 4):
    print(val) 

答案 2 :(得分:4)

它与第二个值是pass(一个所谓的sentinel值)有关,这确保了迭代的对象是可调用的,即。一个功能。 因此,对于iter()执行的每次迭代,它都会在传递的对象上调用__next__()

iter()有两种不同的行为,

  • 没有哨兵价值
  • 带有哨兵值

文档中的示例非常适合理解它

with open("mydata.txt") as fp:
    for line in iter(fp.readline, "STOP"): #fp.readline is a function here.
        process_line(line)

答案 3 :(得分:3)

查看文档:{​​{3}}

iter中存在第二个参数时,第一个参数的处理方式会有很大不同。它应该是在每个步骤中调用的函数。如果它返回sentinel(即第二个参数),则迭代停止。例如:

l=[1,2,3,4,5,6]

index = -1
def fn():
    global index
    index += 1
    return l[index]

for val in iter(fn, 4):
    print (val)

编辑:如果您想循环浏览列表并在看到哨兵时停止,那么我建议您这样做:

for val in l:
    # main body
    if val == 4:
        break

答案 4 :(得分:3)

请记住,类是Python中的对象。

>>> callable(list)
True

表示列表本身是可调用的,而不是可调用的实例。如你所见,他们不是:

>>> callable([])
False

事实上,Python中的所有类都是可调用的 - 如果它们没有像list那样的文字,这是实例化它们的常用方法。考虑:

def MyClass:
     pass

a = MyClass()

最后一行调用MyClass类对象,该对象创建一个实例 - 因此,MyClass必须是可调用的。但是你不希望实例可以调用,因为MyClass本身没有定义__call__

另一方面, MyClass的类(即其元类,type

>>> type.__call__
<slot wrapper '__call__' of 'type' objects>

这使得MyClass可以调用。

答案 5 :(得分:1)

  

为什么callabe(list)返回true但是callable(l)不返回?

因为list是Python内置函数,而l是列表。

答案 6 :(得分:0)

也许您正在寻找类似的东西?

>>> l = [1,2,3,4,5,6]
>>> l_it = iter(l)
>>> while True:
...     next_val = next(l_it, None)
...     if not next_val:
...             break
...     print(next_val)