这段代码有什么问题?
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) 不返回?
编辑 这里应该首选什么方法:
来自
iter
帮助:
iter(...)
iter(集合) -> 迭代器
iter(可调用,哨兵) -> 迭代器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) 不返回 true?
因为
list
是返回新列表对象的函数。函数是可调用的(这就是函数的作用 - 它被调用),而该函数返回的实例 - 新列表对象 - 不是。
当使用两个参数调用时,
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
类型对象和列表实例之间存在很大且重要的区别,这在与iter
一起使用时表现出来。
要迭代列表直到到达哨兵,您可以使用
itertools.takewhile
:
import itertools
for val in itertools.takewhile(l, lambda x: x!= 4):
print(val)
它与传递的第二个值(所谓的哨兵值)有关,这确保了正在迭代的对象是可调用的,即。一个函数。 因此,对于
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)
查看文档: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
请记住,类是 Python 中的对象。
>>> callable(list)
True
意味着 list 本身是可调用的,而不是它的实例是可调用的。正如您所见,它们不是:
>>> callable([])
False
事实上,Python 中的所有类都是可调用的 - 如果它们没有像
list
这样的文字,这是实例化它们的常用方法。考虑:
def MyClass:
pass
a = MyClass()
最后一行调用
MyClass
类对象,它创建一个实例 - 因此,MyClass
必须是可调用的。但您不会期望 instance 是可调用的,因为 MyClass
本身并没有定义 __call__
。
另一方面,类of
MyClass
(即它的元类,type
)确实:
>>> type.__call__
<slot wrapper '__call__' of 'type' objects>
这就是使
MyClass
可调用的原因。
为什么 callabe(list) 返回 true 而 callable(l) 不返回 true?
因为
list
是 Python 内置函数,而 l
是一个列表。
原因已在之前的回答中解释过。
这是修改后的代码,可以在Python中执行。
l = [1,2,3,4,5,6]
l.reverse()
for val in iter(l.pop, 4):
print (val)
也许您正在寻找类似的东西?
>>> 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)