这是使用itertools.cycle()知道索引的一种方法吗?

时间:2014-10-23 15:01:53

标签: python indexing cycle itertools

我需要循环一个列表,并在到达最后一个项目时返回第一个元素。

来自itertoolscycle对象专为此而设计。

myList = [1,2,3,4,5,6,7,8,9]

i = 0
for item in cycle(myList):
    index = i%9
    print (index)
    i += 1

除了使用i变量之外还有其他方法吗?

2 个答案:

答案 0 :(得分:3)

您可以使用enumerate

for i, item in enumerate(cycle(myList)):

以下是演示:

>>> from itertools import cycle
>>> for i, item in enumerate(cycle([1, 2, 3])):
...     print i, item
...
0 1
1 2
2 3
3 1
4 2
5 3

你甚至可以给出一个特定的号码:

for i, item in enumerate(cycle([1, 2, 3]), 10): # Start at 10

阅读@ DSM的评论,我发现您可能希望将来电转为cycleenumerate

>>> for i, item in cycle(enumerate([1, 2, 3])):
...     print i, item
...
0 1
1 2
2 3
0 1
1 2
2 3

这将导致i引用列表中item的索引,而不是充当计数器变量。

答案 1 :(得分:0)

作为对此的扩展,我正在寻找一种索引cycle对象中的方法。

为此,您可以使用__getitem__方法编写一个自定义类来代替cycle

from itertools import cycle, takewhile, dropwhile


class CyclicalList:
    def __init__(self, initial_list):
        self._initial_list = initial_list

    def __getitem__(self, item):
        if isinstance(item, slice):
            if item.stop is None:
                raise ValueError("Cannot slice without stop")
            iterable = enumerate(cycle(self._initial_list))
            if item.start:
                iterable = dropwhile(lambda x: x[0] < item.start, iterable)
            return [
                element
                for _, element in takewhile(lambda x: x[0] < item.stop, iterable)
            ]

        for index, element in enumerate(cycle(self._initial_list)):
            if index == item:
                return element

    def __iter__(self):
        return cycle(self._initial_list)

允许您使用常规索引/切片符号。

myList = CyclicalList([1,2,3,4,5,6,7,8,9])
myList[10]  # 2
myList[10:20]  # [2, 3, 4, 5, 6, 7, 8, 9, 1, 2]

根据您的需要,您可能还想实现其他列表方法并进行优化。但这解决了索引到循环对象中的主要思想。