此代码有什么问题?
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)不会?
修改 这里应该首选什么方法:
答案 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)