枚举从不同的列表项开始

时间:2015-02-27 18:07:38

标签: python list enumerate

我对python中内置的“枚举”函数有点熟悉。我明白,如果我有这样的清单:

list = [A, B, C, D]

该枚举将如下编号:

list = [(A,0), (B,1), (C,2), (D,3)]

有没有办法枚举以不同的列表项开头?例如,从C而不是A?

开始
list = [(A,2),(B,3),(C,0),(D,1)]

或者,有没有比使用枚举更好的方法呢?

我正在尝试的是编写程序,用户可以选择歌曲的根音符/键,并且程序将返回哪些音符是该音阶的和弦。例如,大和弦是音阶中的第一个第三和第五个音符。所以在C的关键C-E-G。我认为最好的方法是枚举音乐键列表并打印第一,第三,第五项等。

5 个答案:

答案 0 :(得分:3)

如果它超过了迭代的长度,即使你以偏移开始,

开箱即用的枚举也不会包裹索引。说通过简单的包装器扩展包装功能是微不足道的

for index, elem in ((index % len(lst), elem) for index, elem in enumerate(lst,2)):
    print (index, elem)


(2, 'A')
(3, 'B')
(0, 'C')
(1, 'D')

如果您多次使用

,我们鼓励使用包装器
enumerate_wrap = lambda it, offset: ((index % len(it), elem)
                                     for index, elem in enumerate(it, offset))
for index, elem in enumerate_wrap(lst, 2):
    print (index, elem)


(2, 'A')
(3, 'B')
(0, 'C')
(1, 'D')

答案 1 :(得分:1)

可能不是很优雅:

>>> list2 = [(j, i%4) for i, j in enumerate(list,2)]
>>> list2
[('A', 2), ('B', 3), ('C', 0), ('D', 1)]

答案 2 :(得分:0)

首先:

list(enumerate(["A", "B", "C", "D"])) == [(0,"A"), (1,"B"), (2,"C"), (3,"D")]

然后:enumerate按顺序列举一个列表。如果您想以不同的顺序枚举它,您需要首先重新排序列表:

["Elephant", "Ant", "Dog"] 

将枚举为

print list(enumerate(["Elephant", "Ant", "Dog"]))
[(0, 'Elephant'), (1, 'Ant'), (2, 'Dog')]

然而

print list(enumerate(sorted(["Elephant", "Ant", "Dog"])))
[(0, 'Ant'), (1, 'Dog'), (2, 'Elephant')]

将首先按字母顺序对列表进行排序,然后枚举它。

答案 3 :(得分:0)

假设你先知道你想要作为枚举开始的元素的索引,这里有两种可能性,一种是使用列表和枚举,一种是使用numpy。

mylist = ['A', 'B', 'C', 'D']
for index, value in enumerate(mylist):
    print(index, value)
(0, 'A')
(1, 'B')
(2, 'C')
(3, 'D')

简单地“包装”从索引2开始的列表:

varlist = mylist[2:]+mylist[:2]
for index, value in enumerate(varlist):
    print(index, value)
(0, 'C')
(1, 'D')
(2, 'A')
(3, 'B')

使用Numpy:

import numpy as np
myarr = np.array(mylist)
rolled = np.roll(myarr, 2)
for index, value in enumerate(rolled):
    print(index, value)
(0, 'C')
(1, 'D')
(2, 'A')
(3, 'B')

答案 4 :(得分:0)

from itertools import cycle, islice, chain

def rolled(start,lst):
    cycled = cycle(range(len(lst)))
    list(islice(cycled, None, start))
    tail = islice(lst, start, len(lst))
    head = islice(lst, start)
    yield from zip(chain(head, tail), cycled)

In [59]: for ind,chord in rolled(2):
   ....:     print(ind,chord)
   ....:     
A 2
B 3
C 0
D 1
In [60]: list(rolled(2))
Out[60]: [('A', 2), ('B', 3), ('C', 0), ('D', 1)]

无法想出一个更好的方法来跳过循环中的第一个数字,但这应该是更大列表中最快的解决方案之一。

您可以使用循环来跳过元素,但它看起来有点难看:

def rolled(start,lst):
    cycled = cycle(range(len(lst)))
    for _ in islice(cycled, None, start):
        pass
    tail = islice(lst, start, len(lst))
    head = islice(lst, start)
    yield from zip(chain(head, tail), cycled)