Как извлечь все значения для одного набора ключей

#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 благодарит за обновленный ответ. Ответы были моими предположениями вместо точного вывода с консоли 🙂