#python #dictionary
#python #словарь
Вопрос:
Как извлечь все значения из одного набора ключей, без записи всех ключей, для словаря с двумя (или более) записями, не используя цикл, например:
dictionary={'a':{'a1':'1','a2':'2','a3':'3'},'b':{'a1':'x','a2':'y','a3':'z'}}
dictionary[*]['a1']
Я смогу вернуть ‘1’ и ‘x’
Комментарии:
1. Что вы подразумеваете под «без записи всех ключей»?
2. Ну, вы могли бы сделать
map(operator.itemgetter('a1'), dictionary.itervalues())
— который не использует явный цикл, но не уверен, почему вы все равно пытаетесь избежать цикла?
Ответ №1:
Похоже, вы ищете понимание списка.
dictionary={'a':{'a1':'1','a2':'2','a3':'3'},'b':{'a1':'x','a2':'y','a3':'z'}}
output = [dictionary[x]['a1'] for x in dictionary]
print output
Вывод:
['1', 'x']
Если есть опасения, что подраздел a1
существует не для всех значений, то нам, вероятно, следует переключиться на dict.get
, который вернет None
для всех тех случаев, когда a1
его нет в словаре.
output = [dictionary[x].get('a1') for x in dictionary]
С другой стороны, если нам не нужно заполняющее None
значение, мы можем поступить так, как предложил Джон Клементс, и использовать фильтр.
output = [dictionary[x]['a1'] for x in dictionary if 'a1' in dictionary[x]]
Комментарии:
1. вероятно, лучше использовать
dict.get
.2. Если
None
s (или другое значение по умолчанию не требуется), то, возможно, даже[dictionary[x]['a1'] for x in dictionary if 'a1' in dictionary[x]]
3. @JonClements, что эффективнее, используя ваше выше или
[x.get("a1") for x in dictionary.itervalues() if x.get("a1")]
4. @PadraicCunningham Более эффективно и гибко проверять наличие ключа в dict, чем извлекать значение ключа дважды. Особенно там, где
None
является допустимым значением, и в этом случае вам придется использовать объекты sentinel сget
, чтобы отфильтровать их в списке-comp.5. @JonClements, однако, если вы используете
if x.get("a1")
, не будет никаких значений None, какin
проверка сравнивается сdict.get
?
Ответ №2:
import operator
dictionary={'a':{'a1':'1','a2':'2','a3':'3'},'b':{'a1':'x','a2':'y','a3':'z'}}
map(operator.itemgetter('a1'), dictionary.itervalues())
OUTPUT:
['1', 'x']
В случае, если вам нужно несколько элементов
result = map(operator.itemgetter('a1', 'a2'), dictionary.itervalues())
zip(*result)
OUTPUT:
[('1', 'x'), ('2', 'y')]
Если вы хотели в качестве словаря
keys = ['a1', 'a2']
values = map(operator.itemgetter(*keys), dictionary.itervalues())
dict(zip(keys, zip(*values)))
OUTPUT:
{'a1': ('1', 'x'), 'a2': ('2', 'y')}
Комментарии:
1. соответствует ли ответ вопросу?
2. Я думаю… какие-либо предложения / улучшения вы видите?
3. @Aedil Я думаю, что дело скорее в том, что
[('1', 'x')]
это просто['1', 'x']
— не совсем уверен, как вам удалось вставить список из одного элемента с кортежем с кодом (который выглядит довольно похоже на мой комментарий :))4. @JonClements … это была ошибка, обновленный вывод, и да, только что увидел ваш комментарий, это точно то же самое 🙂
5. @PadraicCunningham благодарит за обновленный ответ. Ответы были моими предположениями вместо точного вывода с консоли 🙂