问题
I am currently trying to get the index of a value from a dictionary and unsure what to try.
My dictionary is:
midi2notes = {
'c':("0","12","24","36","48","60","72","84","96","108","120"),
'des':("1","13","25","37","49","61","73","85","97","109","121"),
'd':("2","14","26","38","50","62","74","86","98","110","122"),
'ees':("3","15","27","39","51","63","75","87","99","111","123"),
'e':("4","16","28","40","52","64","76","88","100","112","124"),
'f':("5","17","29","41","53","65","77","89","101","113","125"),
'ges':("6","18","30","42","54","66","78","90","102","114","126"),
'g':("7","19","31","43","55","67","79","91","103","115","127"),
'aes':("8","20","32","44","56","68","80","92","104","116"),
'a':("9","21","33","45","57","69","81","93","105","117"),
'bes':("10","22","34","46","58","70","82","94","106","118"),
'b':("11","23","35","47","59","71","83","95","107","119")
}
Example: I want to get the index of value-"60" from key- 'c'. Which should be 5. What would be the most efficient/quickest way to go about this.
回答1:
I would do:
midi2notes['c'].index('60')
This will raise an ValueError
if the index isn't found, but if the numbers are usually in the tuple, it'll be hard to beat the optimized C backend.
>>> midi2notes = {
... 'c':("0","12","24","36","48","60","72","84","96","108","120"),
... 'des':("1","13","25","37","49","61","73","85","97","109","121"),
... 'd':("2","14","26","38","50","62","74","86","98","110","122"),
... 'ees':("3","15","27","39","51","63","75","87","99","111","123"),
... 'e':("4","16","28","40","52","64","76","88","100","112","124"),
... 'f':("5","17","29","41","53","65","77","89","101","113","125"),
... 'ges':("6","18","30","42","54","66","78","90","102","114","126"),
... 'g':("7","19","31","43","55","67","79","91","103","115","127"),
... 'aes':("8","20","32","44","56","68","80","92","104","116"),
... 'a':("9","21","33","45","57","69","81","93","105","117"),
... 'bes':("10","22","34","46","58","70","82","94","106","118"),
... 'b':("11","23","35","47","59","71","83","95","107","119")
... }
>>> midi2notes['c'].index('60')
5
>>> midi2notes['c'].index('180')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: tuple.index(x): x not in tuple
>>>
回答2:
If you need to do this often, instead of looking up the index each time, just create a dict
that maps the values back to indices:
midi2notes_map = {key: {value: index for index, value in enumerate(tup)}
for key, tup in midi2notes.items()}
Then you can just do this:
midi2notes_map['c']['60']
Or, alternatively:
midi2notes_map = {(key, value): index
for key, tup in midi2notes.items()
for index, value in enumerate(tup)}
midi2notes_map['c', 60]
This should be on the order a 5x more efficient each time you do a lookup (since you just need to hash the key, instead of linearly searching a tuple of 10 items)… But of course building up the map takes some time, so if you're only doing a couple of lookups, it may not be worth it.
Of course you should make sure that the performance of this lookup really is relevant before worrying about it. (I'm guessing the slowest implementation you could come up with, using an explicit nested loop, would still be fast enough to play a MIDI sequence…) And, if it is, set up a test using timeit
with your actual data and usage patterns to find out what's actually fastest.
回答3:
With enumerate()
:
>>> for x,y in enumerate(midi2notes['c']):
... if y == "60":
... print x
...
5
来源:https://stackoverflow.com/questions/16159766/python-dictionary-index-of-a-value