每次调用函数时,我都试图让我的函数逐个返回列表中的项目。我有这段代码:
def abc():
ls = ['a', 'b', 'c']
for i in ls:
ls.append(i)
yield i
我可以在终端上输入类似的内容并按住next()
来获取列表中的下一个项目。
>>>ab = abc()
>>>next(ab)
'a'
>>>next(ab)
'b'
>>>next(ab)
'c'
>>>next(ab)
'a'
>>>next(ab)
'b'
每次调用next时它都应该永远存在。我不想在终端中重复输入next(ab)
,而是每次调用函数abc()
时都要让我的函数执行所有操作(返回列表中的下一项)。
答案 0 :(得分:3)
基本上你正在寻找一个闭包函数:
def func():
seq = ['a', 'b', 'c']
ind = [-1]
def inner():
ind[0] += 1
return seq[ind[0]%len(seq)]
return inner
>>> f = func() # One call is still required after that the
# returned inner function can maintain the state.
>>> f()
'a'
>>> f()
'b'
>>> f()
'c'
>>> f()
'a'
在Python 3中,我们可以使用ind
关键字,而不是将nonlocal
定义为列表。
或使用itertools.cycle
:
from itertools import cycle
def func(seq):
return cycle(seq).next
...
>>> f = func('abc')
>>> f()
'a'
>>> f()
'b'
>>> f()
'c'
>>> f()
'a'
>>> f()
'b'
答案 1 :(得分:2)
您需要chown
。
每次函数调用发生时
queue
这将为您提供所需的行为。
编辑:
x=[1,2,3]
k= x.pop(0)
x.append(k)
return k
答案 2 :(得分:1)
您使用的函数使用越来越多的内存,因为它会附加到每次迭代的列表中。改进是维持一个指数:
def abc():
ls = ['a', 'b', 'c']
i = 0;
while True:
yield ls[i]
i = (i+1) % len(ls)
你所拥有的正是你所需要的。它是生成器。通常,您不会直接致电next()
。通常,您将使用循环来处理生成器生成的值:
for thing in abc():
print(thing)
由于您的生成器永远不会抛出StopIteration
异常,因此for循环将永远不会结束。
答案 3 :(得分:0)
这需要创建一个更高阶的函数,它将使用闭包来创建一个辅助函数来做你想要的。
def create_wrapper(func):
iter = func()
def wrapper():
return next(iter)
return wrapper
ab = create_wrapper(abc)
ab()
>>> 'a'
ab()
>>> 'b'
等等。
以下是上述代码上下文中高阶函数和闭包的快速介绍 -
在上面的代码中,func实际上是一个函数引用,注意我们如何在abc之后没有parens的情况下调用create_wrapper(abc),所以它实际上并没有执行abc()。然后我们创建一个iter对象并创建一个名为wrapper的子函数。我们在子函数中引用iter对象,即使它是在父函数中定义的。这种用法称为闭包。当我们将函数引用返回给包装器时,create_wrapper超出范围,因此在其中使用的任何变量都应该包括iter。但是因为它在子函数中被引用,它继承了它的父级,所以它被保留了。
BTW - 通过附加到列表创建无限迭代器的方式非常聪明:-)但它显然存在内存溢出的危险。还有其他方法可以创建无限迭代器。查看https://docs.python.org/3/library/itertools.html。