0

我目前正在尝试从字典中获取值的索引,但不确定要尝试什么。

我的字典是:

    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")
    }

示例:我想从 key-'c' 中获取 value-"60" 的索引。应该是 5。什么是最有效/最快的方法。

4

3 回答 3

7

我会做:

midi2notes['c'].index('60')

如果未找到索引,这将引发一个ValueError错误,但如果数字通常在元组中,则很难击败优化的 C 后端。

>>> 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
>>> 
于 2013-04-23T02:15:44.597 回答
4

如果您需要经常这样做,而不是每次都查找索引,只需创建一个dict将值映射回索引的方法:

midi2notes_map = {key: {value: index for index, value in enumerate(tup)}
                  for key, tup in midi2notes.items()}

然后你可以这样做:

midi2notes_map['c']['60']

或者,或者:

midi2notes_map = {(key, value): index
                  for key, tup in midi2notes.items()
                  for index, value in enumerate(tup)}

midi2notes_map['c', 60]

每次进行查找时,这应该会提高 5 倍的效率(因为您只需要对键进行散列,而不是线性搜索 10 个项目的元组)......但是当然构建地图需要一些时间,所以如果您只进行了几次查找,这可能不值得。

当然,在担心它之前,您应该确保此查找的性能确实相关。(我猜你能想出的最慢的实现,使用一个显式的嵌套循环,仍然足够快来播放一个 MIDI 序列……)如果是这样,使用timeit你的实际数据和使用模式设置一个测试找出实际上最快的。

于 2013-04-23T02:20:17.977 回答
1

enumerate()

>>> for x,y in enumerate(midi2notes['c']):
...     if y == "60":
...         print x
... 
5
于 2013-04-23T02:18:35.033 回答