python: объединение ключей из нескольких словарей? - PullRequest
11 голосов
/ 09 марта 2011

У меня есть 5 словарей, и я хочу объединить их ключи.

alldict =  [dict1, dict2, dict3, dict4, dict5]

Я пытался

allkey = reduce(lambda x, y: set(x.keys()).union(y.keys()), alldict)

но это дало мне ошибку

AttributeError: 'set' object has no attribute 'keys'

Я делаю это неправильно? Я использую обычный forloop, но мне интересно, почему вышеприведенный код не работает.

Ответы [ 5 ]

40 голосов
/ 09 марта 2011

Я думаю, что @chuck уже ответил на вопрос, почему он не работает, но проще было бы помнить, что метод union может принимать несколько аргументов:

allkey = set().union(*alldict)

делает то, что вы хотите, без каких-либо петель или лямбд.

9 голосов
/ 09 марта 2011

Ваше решение работает для первых двух элементов в списке, но затем dict1 и dict2 сведены в набор, и этот набор помещается в вашу лямбду как x. Так что теперь x больше не имеет метода keys().

Решение состоит в том, чтобы сделать x набором с самого начала, инициализируя сокращение пустым набором (который оказывается нейтральным элементом объединения).

Попробуйте с инициализатором:

allkey = reduce(lambda x, y: x.union(y.keys()), alldict, set())

Альтернативой без лямбд будет:

allkey = reduce(set.union, map(set, map(dict.keys, alldict)))
2 голосов
/ 09 марта 2011

Простая стратегия для нефункциональных нейронов (каламбур предназначен):

allkey = []

for dictio in alldict:
    for key in dictio:
        allkey.append(key)

allkey = set(allkey)

Мы можем преобразовать этот код в намного более сортировочную форму, используя заданные значения:

allkey = {key for dictio in alldict for key in dictio}

Этот однострочный текст по-прежнему очень удобочитаем по сравнению с обычным циклом for. Ключом для преобразования вложенного цикла в список или установки понимания является запись внутреннего цикла (который изменяется во вложенном цикле) как последний индекс (то есть for key in dictio).

0 голосов
/ 16 июля 2013
set().union(dict1.keys(),dict2.keys()...)

Я попробовал список, и он не сработал, поэтому просто разместил его здесь для всех.

0 голосов
/ 09 марта 2011

Просто еще один способ, потому что, что сено:

a={}; [ a.update(b) for b in alldict ] and a.keys()

или чуть более таинственный

reduce(lambda a, b: a.update(b) or a, alldict, {}).keys()

(я обижен, что нет встроенногофункция, эквивалентная

def f(a,b):
   r = {}
   r.update(a)
   r.update(b)
   return r

есть?)

...