2010-01-20 64 views
2

以下代码的最佳单行替换是什么?我确信有一个更聪明的方法。高效搜索二元组

choices = ((1, 'ONE'), (2, 'TWO'), (3, 'THREE')) 
some_int = 2 
for choice in choices: 
    if choice[0] == some_int: 
     label = choice[1] 
     break; 
# label == 'TWO' 
+0

如果某个'choice [0]'出现两次会发生什么?你想要第一还是最后?请注意,'dict(choices)'方法将使用最后一个'dict(反转(选择))',如果这很重要,则会给出第一个。 – 2010-01-23 21:01:43

回答

14
labels = dict(choices) 
label = labels[some_int] 

,你可以,当然,加入这一成一衬,如果你不需要labels其他地方。

+0

我知道它一定很简单! – Sam 2010-01-22 13:32:50

6

您可以使用字典。

>>> choices = { 1: 'ONE', 2: 'TWO', 3: 'THREE' } 
>>> label = choices[2] 
>>> label 
'TWO' 
+1

数据结构是一个二元组,因为这是您在Django中定义字段选择的方式。 – Sam 2010-01-22 13:35:34

3

如果你真的找一个衬垫...

label = dict(choices)[some_int] 

就是

>>> choices = ((1, 'ONE'), (2, 'TWO'), (3, 'THREE')) 
>>> dict(choices)[1] 
'ONE' 
5

对于一次性的搜索,如果你致力于与开始数据结构,并且不能将其构建到字典中所需的时间分摊,并且不知道起始结构是否已排序(因此不能对分搜索),但没有比简单线性更快的算法搜索。你可以优雅地表达它,例如在Python 2.6或更高:

label = next((lab for cho, lab in choices if cho==someint), None) 

假设你想要的标签为None,如果没有选择匹配 - 或者,如果你想在这种情况下被提出的一个例外,只是

label = next(lab for cho, lab in choices if cho==someint) 

或旧的Python版本

label = (lab for cho, lab in choices if cho==someint).next() 

,但我怀疑的性能将会改变很多(容易timeit来衡量,如果你在乎,但在这种情况下,你需要提供的0123一些现实的例子- 典型的长度,无法选择的机会等等,等等)。