如何制作一个将 return 列表中的项目一次一个的函数?

How to make a function that will return items in a list one at a time?

我试图在每次调用函数时将我的函数return项逐一添加到列表中。我有这个代码:

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() 时都执行所有操作(return 列表中的下一项)。

您需要 queue.

每次函数调用发生

x=[1,2,3]
k= x.pop(0)
x.append(k)
return k

这将使您获得所需的行为。

编辑:

ls = ['a', 'b', 'c']
def abc():

    k= ls.pop(0)
    ls.append(k)
    return k

print abc()
print abc()
print abc()
print abc()
print abc()

您的函数使用越来越多的内存,因为它会在每次迭代时追加到列表中。一个改进是维护一个索引:

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 循环永远不会结束。

基本上你在寻找一个闭包函数:

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 中,我们可以使用 nonlocal 关键字而不是将 ind 定义为列表。

或使用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'

这需要创建一个高阶函数,该函数将使用闭包创建一个辅助函数来执行您想要的操作。

def create_wrapper(func):
    iter = func()
    def wrapper():
        return next(iter)
    return wrapper

ab = create_wrapper(abc)
ab()
>>> 'a'
ab()
>>> 'b'

以此类推

这里是对上述代码上下文中高阶函数和闭包的快速介绍 -

在上面的代码中,func实际上是一个函数引用,注意我们调用create_wrapper(abc)时没有在abc后面加上括号,所以它实际上并不是在执行abc()。然后我们创建一个 iter 对象并创建一个名为 wrapper 的子函数。我们在子函数中引用 iter 对象,即使它是在父函数中定义的。这种用法称为闭包。当我们 return 对包装器的函数引用时, create_wrapper 超出范围,其中使用的任何变量也应该超出范围 - 包括 iter。但是因为它在其父函数之外的子函数中被引用,所以 iter 被保留了。

顺便说一句 - 通过附加到列表来创建无限迭代器的方式非常聪明 :-) 但它显然存在内存溢出的危险。还有其他方法可以创建无限迭代器。查看 https://docs.python.org/3/library/itertools.html