Python: проверьте, является ли какой-либо элемент списка ключом в словаре - PullRequest
3 голосов
/ 25 августа 2011

Учитывая следующий код

all_options = { "1": "/test/1", "2": "/test/2", "3": "/test/3" }
selected_options = [ "1", "3" ]

Как получить записи из all_options , где ключ соответствует записи в selected_options ?

Я начал с использования List Conceptionsion , но я застрял в последнем предложении:

final = ()
[ final.append(option) for option in all_options if ... ]

Спасибо

Ответы [ 5 ]

5 голосов
/ 25 августа 2011

Так же, как это?

>>> dict((option, all_options[option]) for option in selected_options if option in all_options)
{'1': '/test/1', '3': '/test/3'}

Начиная с Python 2.7 и 3, вы можете использовать синтаксис dict :

{option : all_options[option] for option in selected_options if option in all_options}

Или, если вы просто хотите значения:

>>> [all_options[option] for option in selected_options if option in all_options]
['/test/1', '/test/3']
1 голос
/ 25 августа 2011

Как получить записи из all_options, где ключ соответствует записи в selected_options?

С пониманием.У нас есть два вида: списочные и генераторные.

Обратите внимание, что это зависит от того, что вы подразумеваете под «записями».Если вам нужен dict с совпадающими парами ключ / значение, вам понадобится понимание, которое создает пары ключ / значение, а затем используйте его для создания dict, передавая его конструктору dict.

Существует специальное синтаксическое правило, которое гласит, что если мы вызываем что-то вызываемое (например, конструктор класса) только с одним аргументом, и этот аргумент является генератором, то нам нужна только одна пара скобок (вместо двух: один для вызова функции, а другой для обозначения понимания как понимания).Это позволяет нам писать очень естественные вещи.

С другой стороны, если вы просто хотите list ключей, то вы можете просто использовать понимание списка.(Вы также можете передать генераторное понимание конструктору list.)

Я начал с использования списочного понимания ...

У вас естьнеправильное представление о том, как они работают.Вы не используете их, чтобы выполнить действие повторно;Вы используете их для многократного вычисления результата.Вы не сделаете вызов append в первой части оператора, потому что (a) понимание уже строит последовательность для вас, поэтому нет причин создавать другую пустую последовательность для добавления;(b) вызов append возвращает None после выполнения добавления, поэтому в итоге вы получите список значений None, которые впоследствии выбрасываете.

Понимание списка создает значение .Генераторное понимание также создает значение, но это генератор (поэтому вы должны извлечь его значения, чтобы использовать их).

Итак, как нам написать код?

A listключей выглядит следующим образом: для каждого ключа в dict ( итерации по dict итерации по его ключам ) мы хотим, чтобы этот ключ (без модификации), только если ключ находится в нашемдругое list.То есть мы хотим [key for key in all_options if key in selected_options].И это именно то, как вы пишете это на Python.Язык вряд ли мог бы читать более естественно, оставаясь однозначным.

A dict пар ключ-значение выглядит так: для каждой пары ключ-значение в парах ключ-значение dict,мы хотим эту пару, только если ключ находится в нашем другом list.Мы хотим сделать dict, используя эти пары ключ-значение, поэтому мы заключаем понимание в конструктор dict.Чтобы получить пары ключ-значение из dict, мы перебираем его .items().Итак, мы хотим получить dict, построенный из ключа и значения, для каждого ключа и значения в элементах исходного dict, где ключ находится в другом list.И снова, это именно то, что мы пишем: dict((key, value) for (key, value) in all_options if key in selected_options).

В более поздних версиях Python мы также можем использовать «dict comp понимание», которое в основном является синтаксическим сахаром, чтобы мы могли написать что-то, что выглядит болеекак понимание списка.

1 голос
/ 25 августа 2011

Вместо этого используйте set(), а используйте операцию пересечения :

>>> final = set(all_options.keys()) & set(selected_options)
>>> print(final)
{'1', '3'}

Вышеприведенное возвращает только ключи, но NullUserException отмечает, что в вопросе может также потребоваться значение, используя сложное понимание:

>>> {x: all_options[x] for x in set(all_options.keys()) & set(selected_options)}
{'1': '/test/1', '3': '/test/3'}

Для полноты вот просто значение:

>>> [all_options[x] for x in set(all_options.keys()) & set(select_options)]
['/test/1', '/test/3']

Ниже неверно. Использование set() повторяет оба списка вместо одного.

Использование наборов лучше при условии, что параметры станут большими. Понимание условного списка проверяет каждый элемент в одном из контейнеров, но пересечение множеств использует преимущества превосходного хеширования Python. Даже понимание списка здесь только ищет нужные клавиши в all_options.

1 голос
/ 25 августа 2011
[option for option in all_options if option in selected_options]

Вы можете захотеть сделать set из selected_options и использовать его вместо этого, если их много.

0 голосов
/ 25 августа 2011

Я не уверен, какое именно содержимое вы пытаетесь вернуть, поэтому я даю пару вариантов:

если вы пытаетесь вернуться: ['1', '3']

[option for option in all_options if option in selected_options]

OR

если вы пытаетесь вернуться: ['/ test / 1', '/ test / 3']

[all_options[option] for option in all_options if option in selected_options]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...