10

这段代码有什么问题?

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)返回Truecallable(l)没有?

编辑 这里应该首选什么方法:

  1. 手动休息
  2. 其他一百人
4

7 回答 7

7

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功能变体。第一个接受集合,第二个接受两个参数 - 函数和标记值。您正在尝试传递集合哨兵值,这是错误的。

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

为什么 callabe(list) 返回 true 而 callable(l) 没有?

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

于 2013-11-08T08:17:59.953 回答
5

当使用两个参数调用时,iter需要一个可调用值和一个标记值。它的行为就像是这样实现的:

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

传入的f必须是callable,这意味着您可以像调用函数一样调用它。list内置是一个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,当使用 with 时会显示出来iter

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

import itertools
for val in itertools.takewhile(l, lambda x: x!= 4):
    print(val) 
于 2013-11-08T08:34:21.827 回答
4

它与传递的第二个值(所谓的哨兵值)有关,这确保了被迭代的对象是可调用的,即。一个函数。因此,对于每一次迭代,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)
于 2013-11-08T08:17:51.500 回答
3

看看文档:http ://docs.python.org/2/library/functions.html#iter

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

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
于 2013-11-08T08:17:23.707 回答
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可调用的。

于 2013-11-08T08:36:50.650 回答
0

为什么 callabe(list) 返回 true 而 callable(l) 没有?

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

于 2013-11-08T08:14:12.257 回答
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)
于 2020-05-28T00:42:03.857 回答