3

I am a freshman in python programming. Now I have a list "lst" like : lst = [(1,'a'), (2,'b'), (2,'c'), (3,'d')] and I want to get a dict "d" from lst. "d" should be {1: ['a'], 2:['b','c'], 3:['d']}.

d = defaultdict(list)

for k,v in lst:
    d[k].append(v)

How can I achieve this using comprehension?

martineau
  • 119,623
  • 25
  • 170
  • 301
Adam Han
  • 33
  • 4
  • 2
    Your approach looks neat to me – nikeros Dec 16 '21 at 15:27
  • comprehensions are just for convenience. You don't have to write everything in comprehension it doesn't offer anything more than a plain for-loop. Your code is readable and concise. – Ch3steR Dec 16 '21 at 15:30
  • I agree with the other comments; your code is fine. If you want to have it on one line just do `for k,v in lst: d[k].append(v)` – It_is_Chris Dec 16 '21 at 15:34

2 Answers2

5

You solution is pretty good. list/dictionary comprehensions are not always the best approach. But If you insist, you can do something like:

from itertools import groupby

lst = [(1, 'a'), (2, 'b'), (2, 'c'), (3, 'd')]

res = {k: [b for a, b in g] for k, g in groupby(lst, key=lambda x: x[0])}
print(res)

output:

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

note: This solution would work if you pass a sorted list, If it's not, make sure you sort the list before using it in the dictionary comprehension (Thanks @Chepner)

sorted_lst = sorted(lst, key=lambda x: x[0])
S.B
  • 13,077
  • 10
  • 22
  • 49
  • 1
    Replace `lst` with `sorted(lst, key=lambda x: x[0])` if it isn't already sorted by the dict keys. – chepner Dec 16 '21 at 15:36
0

What you have is already quite efficient and not that long. It could be converted to a one-liner at the expense of legibility with little or no performance benefit:

like this:

dic = next(g  for g in [{}] if not any(g.setdefault(k,[]).append(v) for k,v in lst))

Or this:

dic = {}; dic.update((k,dic.get(k,[])+[v]) for k,v in lst)
Alain T.
  • 40,517
  • 4
  • 31
  • 51