我想拥有一个可调用的函数(因为iter()需要它),该函数可以为我提供字符串中的顺序字符。
此功能使我的电脑停滞了,我不得不重置计算机。
cnt=0
def myfunc():
global cnt
cnt+=1
yield "abczdef"[cnt]
list(iter(myfunc,'z'))
答案 0 :(得分:2)
您可以将字符串直接用作可迭代项:
def characters(string, sentinel):
for c in string:
if c == sentinel:
break
yield c
>>> list(characters('abczdef', 'z'))
['a', 'b', 'c']
一种更实用的方法,如您所想到的,将是:
from itertools import takewhile
def characters(string, sentinel):
return takewhile(lambda c: c != sentinel, string))
也可以使用iter(callable, sentinel)
表单,但是我发现其他解决方案更易读:
def characters(string, sentinel):
chars = iter(string)
return iter(lambda: next(chars), sentinel)
list(iter(myfunc,'z'))
等效于:
result = []
while True:
x = myfunc()
if x == 'z':
break
result.append(x)
如果您查看致电myfunc()
时发生的情况:
>>> myfunc()
<generator object myfunc at 0x7f1e0f1020a0>
>>> myfunc()
<generator object myfunc at 0x7f1e0f1020f8>
>>> myfunc()
<generator object myfunc at 0x7f1e0f1020a0>
您看到每次调用它都会创建一个新的生成器对象。
很明显,这些对象都不等于'z'
,因此会产生无限循环。
答案 1 :(得分:0)
使用语法iter(f, sentinel)
,第一个参数f
必须是可调用对象,该对象 return
将结果,而不是yield
它。
如果给出了第二个参数 sentinel ,则 object 必须是可调用的对象。在这种情况下创建的迭代器将调用 object ,并且每次对其
__next__()
方法的调用都没有参数;
所以,这就是您要寻找的答案:
cnt=0
def myfunc():
global cnt
cnt += 1
return "abczdef"[cnt]
# ^^^^^^
list(iter(myfunc, 'z'))
正如预期的那样,将得到['b', 'c']
作为结果(注意缺少'a'
:在将cnt
用作字符串索引之前已对其进行了递增,因此您永远都无法访问"abczdef"[0]
):
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> cnt=0
>>> def myfunc():
... global cnt
... cnt += 1
... return "abczdef"[cnt]
...
>>> list(iter(myfunc, 'z'))
['b', 'c']
>>>