Combine multiple dictionaries based on a common key value into one dictionary

I basically have a list of OrderedDicts;

lst = [
    OrderedDict([('type', 'character'), ('letter', 'a')]),
    OrderedDict([('type', 'character'), ('letter', 'b')]),
    OrderedDict([('type', 'character'), ('letter', 'c')]),
    OrderedDict([('type', 'character'), ('letter', 'd')]),
    OrderedDict([('type', 'integer'), ('number', '1')]),
    OrderedDict([('type', 'integer'), ('number', '2')]),
    OrderedDict([('type', 'integer'), ('number', '3')]),
    OrderedDict([('type', 'integer'), ('number', '4')])
]

I want to change this to

lst = [
    OrderedDict([('type', 'character'), ('letter', ['a', 'b', 'c', 'd'])]),
    OrderedDict([('type', 'integer'), ('number', ['1', '2', '3', '4'])])
]

I thought about having a list of values ​​like ['character', 'integer'] and looked through all the dictionaries to try to combine the letter / number in the list, and then create a new list of dictionaries that will be filled with the data that I received. Not sure if this is the best approach though

Rate help

+4
source share
3 answers

, , itertools.groupby. d.items :

from collections import OrderedDict
from itertools import groupby

_map = {'character': 'letter', 'integer': 'number'}

l = [OrderedDict([('type', k), (_map[k], [d[_map[k]] for d in g])]) for k, g in groupby(lst, lambda x: x['type'])]
print(l)
# [OrderedDict([('type', 'character'), ('letter', ['a', 'b', 'c', 'd'])]), OrderedDict([('type', 'integer'), ('number', ['1', '2', '3', '4'])])]
+1

:

lst = [OrderedDict([('type', t), (kind, [d.items()[1][1] for d in lst if d['type'] == t])]) for (t, kind) in set((d['type'], d.items()[1][0]) for d in lst)]

:

[OrderedDict([('type', 'integer'), ('number', ['1', '2', '3', '4'])]), OrderedDict([('type', 'character'), ('letter', ['a', 'b', 'c', 'd'])])]
0

( .) .:

from collections import OrderedDict

lst = [
    OrderedDict([('type', 'character'), ('letter', 'a')]),
    OrderedDict([('type', 'character'), ('letter', 'b')]),
    OrderedDict([('type', 'character'), ('letter', 'c')]),
    OrderedDict([('type', 'character'), ('letter', 'd')]),
    OrderedDict([('type', 'integer'), ('number', '1')]),
    OrderedDict([('type', 'integer'), ('number', '2')]),
    OrderedDict([('type', 'integer'), ('number', '3')]),
    OrderedDict([('type', 'integer'), ('number', '4')])
]

types_found = []  # using a list to maintain original order
types_dict = {}   # using a dict for speed and storage

for entry in lst:
    t = entry.get("type", "unknown")
    if t not in types_dict:
        types_found.append(t)
        types_dict[t] = OrderedDict([("type", t)])
    for k, v in entry.items():
        if k != "type":
            types_dict[t].setdefault(k, []).append(v)

new_list = [types_dict[t] for t in types_found]
# okay, so I did use one list comprehension, but it a simple one :)

, :

  • , "character" "integer"; .
  • , lst.
  • ; , .

Python 3.5. ".items()" ".iteritems()".

0

Source: https://habr.com/ru/post/1663126/


All Articles