Эффективный поиск по двум кортежам - PullRequest
2 голосов
/ 20 января 2010

Какая замена одной строки для приведенного ниже кода? Я уверен, что есть более разумный способ.

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'

Ответы [ 4 ]

14 голосов
/ 20 января 2010
labels = dict(choices)
label = labels[some_int]

Вы можете, конечно, объединить это в одну строку, если вам не нужно labels где-либо еще.

6 голосов
/ 20 января 2010

Вы можете использовать диктовку.

>>> choices = { 1: 'ONE', 2: 'TWO', 3: 'THREE' }
>>> label = choices[2]
>>> label
'TWO'
5 голосов
/ 20 января 2010

Для одноразового поиска, если вы стремитесь начать с этой структуры данных и не можете амортизировать время, необходимое для встраивания ее в словарь, и не знаете, отсортирована ли начальная структура (так что поиск по бисекции не возможен), нет более быстрых алгоритмов, чем простой линейный поиск. Вы можете выразить это элегантно, например в 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, если вам не все равно, но в этом случае вам нужно предоставить некоторые реалистичные примеры choices - типичная длина, вероятность того, что выбор не будет приемлемым и т. Д. и т. д.).

3 голосов
/ 20 января 2010

Если вы действительно ищете один лайнер ...

label = dict(choices)[some_int]

то есть

>>> choices = ((1, 'ONE'), (2, 'TWO'), (3, 'THREE'))
>>> dict(choices)[1]
'ONE'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...