为了账号安全,请及时绑定邮箱和手机立即绑定

如何通过索引循环遍历列表,并在索引 > len(list) 的情况下从头开始?

如何通过索引循环遍历列表,并在索引 > len(list) 的情况下从头开始?

慕的地10843 2023-06-27 10:39:28
精华:对于像这样的列表['A', 'B', 'C'],我试图构建或查找一个函数,该函数将在每次调用时返回列表的下一个元素。在这种情况下,如果调用次数超过 3 次,则将A返回。之后B等等。详细信息和我尝试过的:我有一个['A', 'B', 'C']要应用于不同对象的颜色列表。每次运行代码时,对象的数量可能会有所不同。如果列表中的对象多于颜色,我希望第四个对象具有 color 'A'。因此,正如标题所示,我想通过 和 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测试1# input:runs = 2looper(['A', 'B', 'C'], runs)# output:AB测试2#input :runs = 5looper(['A', 'B', 'C'], runs)#output :ABCABruns正如您所看到的,如果这个简单的函数足够大,它就会崩溃。除此之外,每次调用此函数时,我想从上次调用结束的索引开始。因此,从上一个示例开始,下次调用时:runs = 1looper(['A', 'B', 'C'], runs)那么输出将是:c我还没有完全了解发电机的使用,我只能猜测这将是一种有用的方法。但我发现,如果您想按照生成器表达式与列表理解后的最佳答案循环遍历列表一次,则应该仅使用生成器。据我所知,生成器毕竟没有用,因为在 Python 中重置生成器对象似乎有点复杂。感谢您的任何建议!
查看完整描述

2 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

结合评论中的建议,您可以实现您正在寻找的确切行为。我不会详细介绍生成器的工作原理,因为有经验的人会给出更简洁的答案。我总结一下,生成器的要点是,它们仅在您要求时才yield为您提供下一个元素。生成器与 Python 中的其他任何对象一样都是对象,因此只要您共享同一个生成器对象,您将始终拥有最后一个元素ed的书签。现在通过代码更好地理解:yield


首先我们来概括一下这个looper函数:


def looper(iterable, runs):

    i = cycle(iterable)

    for _ in range(runs):

        print(next(i))

    return i

runs所以现在它允许您在任何可迭代对象上调用一次函数,次数不限。另一方面,如果您打算多次调用它,它将返回创建的生成器以供重用。


现在我们来测试一些案例:


a = [1, 2, 3]


looper(a, 6)

这将打印:


1

2

3

1

2

3

但更重要的是,这还将:


i = looper(a, 2)

looper(i, 2)

looper(i, 2)

笔记:


我们之所以能够做到这一切,是因为itertools.cycle返回了一个生成器对象。


如果您希望在调用之间产生循环效果,则必须将返回的生成器传递给后续调用。例如,如果我们尝试这样做looper(a, 2)几次,我们总是会得到:


  1

  2

这是因为每次我们调用该函数时,我们都会再次调用并从从第一个元素开始的原始列表中cycle创建一个新的生成器。


另一方面,当将生成器传递给函数时,该cycle函数将创建一个新的生成器,但从前一个生成器停止的位置开始。这样,如果您继续传递第一个返回的cycle生成器,您将保留循环效果。


查看完整回答
反对 回复 2023-06-27
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

您在这里提出两个问题。符合您的问题标题的第一个是如何(打印)列表的循环内容(您在此处使用“looper”),而不是破坏代码中提供的大量运行的代码。


我测试了您的代码,实际上,例如,runs = 13,您的代码中断并出现错误代码 IndexError:列表索引超出范围。


我看到你对更好的算法的要求更多,所以我使用 python 下限除法运算符(//)作为循环(或频率),并使用 python 提醒除法(%)作为提醒。


正如我们在数学上所知,5//2 = 2 和 5%2 = 1


这里的算法是通过计算的周期相应地打印所有列表内容,然后打印剩余的提醒。注意python默认索引是从0开始的。


这是我建议的代码


def looper(lst, runs):

    cycle = (runs-1)//len(lst)

    reminder = (runs-1)%len(lst)

    print('cycle', cycle)

    print('reminder', reminder)

    for i in range(cycle):

        for j in lst:

            print(j)

    for index, k in enumerate(lst):

        if index <= reminder:

            print(k)


# runs must be any positive integer

runs = 13

looper(['A', 'B', 'C'], runs)


我已经用 running = 13 对其进行了测试,代码不会中断打印以下内容,如预期的那样


周期 4 提醒 0 A B C A B C A B C A B C A


第二个问题(或要求)是每当这段代码运行时,起始索引不是从0开始,而是从最后一个提醒开始(我们可以将其视为指针),我认为这是另一个主题。但我也可能会回到这里给出这个解决方案。干杯。


查看完整回答
反对 回复 2023-06-27
  • 2 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信