当列表索引超出范围时,Python会在列表上环绕

Das*_*pez 9 python list

我正在寻找一些代码改进,或者我自己实现的预构建版本,因为我认为可能或者应该是实现我想要的更清洁的方式.

我正在编写一个软件来将吉他标签转换为经典表示法,我需要将标签上的数字转换为相应的音符,这对于从起始字符串构建每个字符串音符的列表非常有用.

我有一个音符列表,(a - g#)和一个音品列表(0,21).

注释[fret]在前11个音符中工作正常但在那之后我显然得到了索引错误.

我必须解决的代码是:

notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"]
note = 21
while note >= len(notes):
    note -= 11
    try:
        print notes[note]
    except:
        continue
Run Code Online (Sandbox Code Playgroud)

它有效但看起来有点......很长,有没有更好的方法呢?

Mar*_*ers 21

使用%运算符生成模数:

notes[note % len(notes)]
Run Code Online (Sandbox Code Playgroud)

演示:

>>> notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"]
>>> note = 21
>>> notes[note % len(notes)]
'g#'
Run Code Online (Sandbox Code Playgroud)

或循环:

>>> for note in range(22):
...     print notes[note % len(notes)],
... 
a a# b c c# d e f f# g g# a a# b c c# d e f f# g g#
Run Code Online (Sandbox Code Playgroud)


sma*_*c89 5

另一种选择是使用itertools.cycle

>>> import itertools
>>> notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"]

>>> frets = range(21)
>>> for note, fret in itertools.izip(itertools.cycle(notes), frets):
        print ("[%s, %d]" %(note, fret))

[a, 0]
[a#, 1]
[b, 2]
[c, 3]
[c#, 4]
[d, 5]
[e, 6]
[f, 7]
[f#, 8]
[g, 9]
[g#, 10]
[a, 11]
[a#, 12]
[b, 13]
[c, 14]
[c#, 15]
[d, 16]
[e, 17]
[f, 18]
[f#, 19]
[g, 20]
Run Code Online (Sandbox Code Playgroud)