对于像 的列表['A', 'B', 'C'],我试图构建或找到一个函数,该函数将在每次调用时返回列表的下一个元素。在这种情况下,如果它被调用超过 3 次,A则将被返回。在那之后B等等。
我有一个['A', 'B', 'C']要应用于不同对象的颜色列表。每次运行代码时,对象的数量可能会有所不同。如果列表中的对象多于颜色,我希望第四个对象具有 color 'A'。所以,正如标题所说,我想遍历一个列表 by 和 index 并从头开始 if index > len(list)。以下自定义函数looper将做到这一点。
def looper(lst, runs):
j = 0
for i in range(0, (len(lst)+(runs-(len(lst))))):
if i < len(lst):
print(lst[i])
else:
print(lst[j])
j +=1
Run Code Online (Sandbox Code Playgroud)
# input:
runs = 2
looper(['A', 'B', 'C'], runs)
# output:
A
B
Run Code Online (Sandbox Code Playgroud)
#input :
runs = 5
looper(['A', 'B', 'C'], runs)
#output :
A
B
C
A
B
Run Code Online (Sandbox Code Playgroud)
如您所见,这个简单的函数如果runs变得足够大就会崩溃。此外,每次调用此函数时,我都想从上次调用结束的索引处开始。所以,从上一个例子开始,下次调用它时:
runs = 1
looper(['A', 'B', 'C'], runs)
Run Code Online (Sandbox Code Playgroud)
那么输出将是:
c
Run Code Online (Sandbox Code Playgroud)
我还没有完全了解生成器的使用,我只能猜测这将是一个有用的方法。但是我拿起你应该只使用一台发电机,如果你想在一个列表喜欢循环一次,按在岗顶端回答生成器表达式与列表理解。所以据我所知,生成器毕竟没有用,因为在 Python 中重置生成器对象似乎有点复杂。感谢您的任何建议!
结合评论中的建议,您可以实现您正在寻找的确切行为。我不会详细介绍生成器的工作原理,因为您从有经验的人那里得到了更简洁的答案。我会总结一下,生成器的要点是,只有当您要求时,它们才会yield为您提供下一个元素。生成器和 Python 中的其他任何东西一样都是对象,所以只要您共享同一个生成器对象,您将始终拥有最后一个元素的书签yielded。现在用代码更好地理解:
首先,我们将概括该looper函数:
def looper(iterable, runs):
i = cycle(iterable)
for _ in range(runs):
print(next(i))
return i
Run Code Online (Sandbox Code Playgroud)
因此,现在它允许您runs在任何可迭代对象上使用任意数量的函数调用一次该函数。另一方面,如果您打算多次调用它,它会返回为重用而创建的生成器。
现在让我们测试一些情况:
a = [1, 2, 3]
looper(a, 6)
Run Code Online (Sandbox Code Playgroud)
这将打印:
1
2
3
1
2
3
Run Code Online (Sandbox Code Playgroud)
但更重要的是,这还将:
i = looper(a, 2)
looper(i, 2)
looper(i, 2)
Run Code Online (Sandbox Code Playgroud)
笔记:
我们之所以能够做到这一切,itertools.cycle是因为它返回了一个生成器对象。
如果您想要调用之间的循环效果,则必须将返回的生成器传递给后续调用。例如,如果我们尝试做looper(a, 2)几次,我们总是会得到:
1
2
Run Code Online (Sandbox Code Playgroud)
这是因为每次我们调用该函数时,我们都会cycle再次调用并从从第一个元素开始的原始列表中创建一个新的生成器。
另一方面,当将生成器传递给函数时,该cycle函数将创建一个新的生成器,但从前一个生成器停止。这样,如果您继续传递第一个返回的cycle生成器,则可以保留循环效果。