Мне нужно составить список словарей из диктата. Оригинальный dict должен будет иметь ключи, которые не повторяются, но значения могут. Например:

{ 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}

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

[{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]

Что я пробовал? Я пробовал это, и это работает, но я уверен, что, вероятно, есть лучший способ достичь того же результата.

lofd=[]
origdict = { 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
for i in origdict.items():
    k = i[0]
    v = i[1]
    try:
        d[v].append(k)
    except:
        d = {v:[]}
        d[v].append(k)
    if d not in lofd:
        lofd.append(d)

lofd
[{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]

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

1
Red Cricket 29 Июн 2019 в 04:42

7 ответов

Лучший ответ

Вы можете сделать это, используя понимание списка:

[dict((_, )) for _ in {v: [_k for _k, _v in d.items() if _v ==  v] for v in d.values()}.items()]

Чтобы показать, что это работает

>>> d = { 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
>>> [dict((_, )) for _ in {v: [_k for _k, _v in d.items() if _v ==  v] for v in d.values()}.items()]
[{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]

Примечание . Я не особо знаю, для чего это нужно, но если бы вы могли, я бы предложил использовать dict вместо списка dicts, поскольку это понимание медленнее, чем просто понимание dict. Если возможно, я бы предложил использовать только понимание диктов, которое, на мой взгляд, было бы намного лучше, хотя возвращает список вместо списка, который более питонический или, по крайней мере, имеет больше смысла, особенно если вы можете повторить то же самое с dict.items().

{v: [_k for _k, _v in d.items() if _v ==  v] for v in d.values()}

Это возвращает dict следующим образом:

{68: ['b', 'c', 'x'], 401: ['z', 'aa'], 2: ['a']}
3
Jab 29 Июн 2019 в 03:39

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

a = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2 }
b = []

for key, val in a.items():
    if (any(val in d for d in b)):
        b[next(i for i, d in enumerate(b) if val in d)][val].append(key)
    else:
        d = {}
        d[val] = [key]
        b.append(d)

print(b)

Выход:

[{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
1
Jack Bashford 29 Июн 2019 в 02:11

метод Enumerate () добавляет счетчик к итерируемому и возвращает его в форма перечисляемого объекта.

origdict = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
my_list = []
my_dict = {}

for index, (key, value) in enumerate(origdict.items()):
    if value in my_dict:
        my_dict[value].append(key)
    else:
        #validate is not first index of list
        if index > 0:
            my_list.append(my_dict)
        my_dict = {}
        my_dict[value] = [key]

    #validate last index of list
    if index == len(origdict)-1:
        my_list.append(my_dict)

print(my_list)

O / P :

[{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
0
bharatk 13 Июл 2019 в 04:58

Несколько такой же, но немного оптимизированный:

a  = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
b  = {}
for k,v in a.items():
    val = b.get(v,[])
    val.append(k)
    b[v] = val

lst = []
for k,v in b.items():
    d = dict()
    d[k] = v
    lst.append(d)

print(lst)

Выход:

[{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
0
arajshree 29 Июн 2019 в 02:04

Используйте defuhaltdict в этом случае

from collections import defaultdict
dic = defaultdict(list)
k= { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
for ke, v in k.items():
     dic[v]+=[ke]

print(dict(dic))

Выход

{68: ['b', 'c', 'x'], 401: ['z', 'aa'], 2: ['a']}
0
sahasrara62 29 Июн 2019 в 02:32

Я бы предложил следующее. Непроверенные .

from collections import defaultdict

a  = { 'b': 66, 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}

t = defaultdict(list)
for k, v in a.items():
    t[v].append(k)

o = [dict((p,)) for p in t.items()]
3
Dan D. 29 Июн 2019 в 02:10

Может быть, что-то подобное.

a = { 'b': 68, 'c': 68, 'x': 68, 'z': 401, 'aa':401, 'a': 2}
b = {}

for k, v in a.items():
    b.setdefault(v, []).append(k)

c = [{k: b[k]} for k in b]
print(c)

Выход:

[{68: ['b', 'c', 'x']}, {401: ['z', 'aa']}, {2: ['a']}]
1
BTall 29 Июн 2019 в 02:24