简体   繁体   English

从其他列表项开始枚举

[英]Enumerate starting from a different list item

I'm somewhat familiar with built in "enumerate" function in python. 我有点熟悉python中内置的“枚举”功能。 I understand that if I have a list like this: 我了解如果我有这样的列表:

list = [A, B, C, D]

That enumerate will number it like this: 该枚举将这样编号:

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

Is there a way to enumerate starting with a different list item? 有没有办法从另一个列表项开始枚举? For example starting from C rather than A? 例如从C而不是A开始?

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

Alternatively, is there an even better way than using enumerate to do this? 或者,有没有比使用枚举更好的方法呢?

What I'm attempting is to write program where the user would select the root note/key of a song, and the program would return which notes are in chords for that scale. 我正在尝试编写一个程序,用户可以选择歌曲的根音符/基调,然后程序将返回该音阶中和弦中的音符。 For example a major chord is the first third and fifth notes in a scale. 例如,大和弦是音阶的前三,五音。 So in the key of C its CEG. 因此,在C的密钥中为其CEG。 I thought the best approach would be to enumerate a list of musical keys and print the first, third, fifth, items etc. 我认为最好的方法是枚举音乐键列表并打印第一,第三,第五个项目等。

enumerate out of the box won't wrap over the index if it exceeds the length of the iterable even though you start with an offset. 即使从偏移量开始,如果枚举超出了可迭代的长度,开箱即用的枚举也不会覆盖索引。 Saying that it is trivial enough to extend the wrap over feature by a simple wrapper 说它很简单,可以通过一个简单的包装器扩展包装功能

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')

And a wrapper is encouraged if you would be using in multiple times 如果您要多次使用,则鼓励使用包装器

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')

Might not be very elegant: 可能不是很优雅:

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

First of all: 首先:

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

Then: enumerate enumerates a list in the order it is. 然后: enumerate依次枚举列表。 If you want to enumerate it in a different order, you'll need to reorder the list first: 如果要以其他顺序枚举,则需要首先对列表重新排序:

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

will enumerate as 将枚举为

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

however 然而

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

will first sort the list alphabetically and then enumerate it. 首先将按字母顺序对列表进行排序,然后进行枚举。

Assuming that you know a priori the index of the element you want as your start for the enumeration, here are two possibilities, one using lists and enumerate, one using numpy. 假设您事先知道要作为枚举起点的元素的索引,则有两种可能,一种使用列表和枚举,一种使用numpy。

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

To simply "wrap" the list starting at index 2: 要简单地“包装”从索引2开始的列表:

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

Using Numpy: 使用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')
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)]

Couldn't figure out a nicer way to skip the first numbers from cycled but this should be one of the fastest solutions for a larger list. 无法找到一种更好的方法来跳过循环中的第一个数字,但这对于较大的列表而言应该是最快的解决方案之一。

You could use a loop to skip the elements but it looks a bit ugly: 您可以使用循环来跳过元素,但是看起来有点难看:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM