7

I have a list of dictionaries. How can i group that list by valaues.

list = [{a:1},{b:2},{c:1},{d:3},{e:2}]

Now my result should be like below

1:a,c
2:b,e
3:d

I tried using groupby from itertools. But i couldn't get the required result. I am using python 2.7.

Could you help me achieve this?

Ma0
  • 15,057
  • 4
  • 35
  • 65
Vasantha Kumari
  • 91
  • 1
  • 1
  • 8
  • can you post the `groupby` code you tried? – Ma0 Mar 09 '18 at 09:36
  • Don't name things like builtin types (`list`), that can have bad side effects. Now, you can either go the "how can I use `itertools.groupby`" way or you could roll your own. In either case, you will have to be much more specific in your question and also show some effort. Remember, nobody here is going to do your homework for you. – Ulrich Eckhardt Mar 09 '18 at 09:38
  • Goupby only works if the data is sorted by the same key function, so sort first. – tobias_k Mar 09 '18 at 09:47
  • Also, why do you have a list of dicts, each having a single, unique key? Can't you just have a single dict? – tobias_k Mar 09 '18 at 09:49
  • This feels like a `defaultdict` type issue – Chris_Rands Mar 09 '18 at 09:53

5 Answers5

7

If you want to use groupby, the list has to be sorted by the same key you want to group by.

>>> lst = [{'a':1}, {'b':2}, {'c':1}, {'d':3}, {'e':2}]

>>> keyfunc = lambda d: next(iter(d.values()))

>>> sorted(lst, key=keyfunc)
[{'a': 1}, {'c': 1}, {'b': 2}, {'e': 2}, {'d': 3}]

>>> {k: [x for d in g for x in d] 
...  for k, g in itertools.groupby(sorted(lst, key=keyfunc), key=keyfunc)}
{1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']}
tobias_k
  • 81,265
  • 12
  • 120
  • 179
4

Here's a possible solution without using any library.

def get_dict(list):
    res = {}

    for elem in list:
        k, v = elem.keys(), elem.values()

        if v[0] in res:
            res[v[0]].append(k[0])
        else:
            res[v[0]] = [k[0]]

    return res

With a list like yours, this would output a dictionary with the following format:

{ 1:[a,c], 2:[b, e], 3:[c] }

This is considering you're always going to have the same format as input. If not, you could just adjust what is read and saved.

Berbus
  • 160
  • 3
  • 20
2

This might help.

list = [{"a":1},{"b":2},{"c":1},{"d":3},{"e":2}]
d = {}
for i in list:
    key, value = i.items()[0]
    if value not in d:
        d[value] = [key]
    else:
        d[value].append(key)
print(d)

Output:

{1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']}

Tested in python2.7

Rakesh
  • 81,458
  • 17
  • 76
  • 113
0

Here is a way to do what you are looking for:

list_ = [{"a":1},{"b":2},{"c":1},{"d":3},{"e":2}]
values = set(value for dic in list_ for value in dic.values())

for value in values:
  keys = [list(dic.keys())[0] for dic in list_ if value in dic.values()]
  print("{}: {}".format(value, keys))

Output:

1: ['a', 'c']
2: ['b', 'e']
3: ['d']
Rafael
  • 7,002
  • 5
  • 43
  • 52
0

Here's a solution that uses defaultdict.

from __future__ import print_function
from collections import defaultdict

lst = [{'a': 1}, {'b': 2}, {'c': 1}, {'d': 3}, {'e': 2}]
d = defaultdict(list)

for l in lst:
    val, key = l.items()[0]
    d[key].append(val)

print(d)

Output: defaultdict(<type 'list'>, {1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']})

Felix
  • 2,064
  • 3
  • 21
  • 31