2014-03-02 2 views
7

Ich suche nach Codeverbesserung oder einer vorgefertigten Version von dem, was ich selbst implementiert habe, da ich denke, dass es dort sein könnte oder sollte sauberer Weg, um das zu erreichen, was ich will.Python wickelt sich auf einer Liste herum, wenn der Listenindex außerhalb des Bereichs liegt.

Ich schreibe ein Stück Software, um Gitarrentabulatoren in klassische Notation zu konvertieren, ich muss die Nummer auf einer Registerkarte in die entsprechende Note konvertieren und es wäre nützlich für eine Liste jeder Saitennote aus der Startreihe zu erstellen .

Ich habe eine Liste von Noten, (a - g #) und eine Liste von Bünden (0, 21).

Noten [Bund] funktioniert gut für die ersten elf Noten, aber danach bekomme ich offensichtlich einen Indexfehler.

Der Code, den ich dies umgehen müssen, ist hier:

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 

Es funktioniert, aber es scheint ein wenig ... lang, gibt es einen besseren Weg, dies zu tun?

+0

verwenden Werden Sie nicht "d #" zu vergessen? Wenn dies der Fall ist, ist es ein guter Weg, "%" wie "notes [note% len (notes)]" zu verwenden, da dadurch automatisch die Listengröße geändert wird. –

Antwort

14

Verwenden der % operator einen Modul zu erzeugen:

notes[note % len(notes)] 

Demo:

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

oder in einer Schleife:

>>> 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# 
+0

Dang! Beat mich um 16 Sekunden – inspectorG4dget

+0

Das tat es, vielen Dank! – DasSnipez

2

Verwendung der Modulo-Operator:

In [3]: notes = ["a", "a#", "b", "c", "c#", "d", "e", "f", "f#", "g", "g#"] 

In [4]: len(notes) 
Out[4]: 11 

In [5]: note = 11 

In [6]: notes[note] 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 
<ipython-input-6-707e7e351463> in <module>() 
----> 1 notes[note] 

IndexError: list index out of range 

In [7]: notes[note%len(notes)] 
Out[7]: 'a' 

In [8]: notes[note-11] 
Out[8]: 'a' 
2

Weitere Optionen ist 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]