如果index>len(list),如何按索引循环列表并从头开始?

2024-05-18 15:34:27 发布

您现在位置:Python中文网/ 问答频道 /正文

本质:

对于像['A', 'B', 'C']这样的列表,我试图构建或查找一个函数,该函数将在每次调用它时返回列表的下一个元素。在本例中,如果调用它超过三次,那么A将被返回。然后B等等


细节和我的尝试:

我有一个颜色列表['A', 'B', 'C'],我正在应用于不同的对象。每次运行代码时,对象的数量可能会有所不同。如果列表中的对象多于颜色,我希望第四个对象的颜色为'A'。因此,正如标题所说,我想循环遍历一个列表by和index,如果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 = 2
looper(['A', 'B', 'C'], runs)

# output:
A
B

测试2

#input :
runs = 5
looper(['A', 'B', 'C'], runs)

#output :
A
B
C
A
B

如您所见,如果runs变得足够大,这个简单的函数将中断。除此之外,每次调用这个函数时,我想从上次调用结束的索引开始。因此,从上一个示例开始,下一次调用:

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

那么输出将是:

c

由于还没有完全了解发电机的使用,我只能猜测这将是一个有用的方法。但是我发现,如果你想按照帖子Generator Expressions vs. List Comprehension中的顶部答案在列表中循环一次,你应该只使用生成器。据我所知,生成器毕竟没有用处,因为Resetting a generator object in Python似乎有点复杂。谢谢你的建议


Tags: 对象函数in元素列表inputoutputindex
2条回答

结合评论中的建议,您可以获得您想要的确切行为。我不会详细讨论发电机是如何工作的,因为您从有经验的人那里得到了更简洁的答案。我将总结一下,生成器的要点是它们yield为您提供下一个元素,只有在您要求时才提供它。生成器和Python中的其他对象一样,都是对象,因此只要您共享同一个生成器对象,您将始终拥有最后一个元素yield书签。现在要更好地理解代码:

首先,我们将泛化looper函数:

def looper(iterable, runs):
    i = cycle(iterable)
    for _ in range(runs):
        print(next(i))
    return i

因此,现在它允许您在任何iterable上调用一次函数,调用的runs数量与您想要的数量相同。另一方面,如果要多次调用它,它将返回为重用而创建的生成器

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

a = [1, 2, 3]

looper(a, 6)

这将打印:

1
2
3
1
2
3

但更重要的是,这也将:

i = looper(a, 2)
looper(i, 2)
looper(i, 2)

注意事项:

  • 我们之所以能够做到这一切,是因为^{}正在返回一个生成器对象

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

      1
      2
    

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

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

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

我测试了您的代码,实际上对于runs=13,您的代码中断了,错误代码indexer:list index超出范围

我认为您需要更好的算法,所以我使用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)

我已经用runs=13测试了它,代码不会像预期的那样中断打印以下内容

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

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

相关问题 更多 >

    热门问题