0

My list of list looks something like this:

[[4,'apples'],[3,'oranges'],[4,'bananas'],[2,'apples'],[2,'pineapple'],[3,'apples']]

I want to create a dictionary from this, where the values of each item is listed: for example, I want the following output:

{4:'apples','bananas', 3:'oranges','apples', 2:'apples', 'pineapple'}
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
tgugan
  • 15
  • 1

4 Answers4

2

dict.setdefault can help here if you don't want to use collections.defaultdict:

lst = [[4,'apples'],[3,'oranges'],[4,'bananas'],[2,'apples'],[2,'pineapple'],[3,'apples']]

dct = {}

for num, name in lst:
    dct.setdefault(num, []).append(name)

print(dct)
#{2: ['apples', 'pineapple'],
# 3: ['oranges', 'apples'],
# 4: ['apples', 'bananas']}

However defaultdict is generally the better and more general solution.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
  • and I benched it just by curiosity and it's faster than defaultdict, even if you create a list at each iteration that is sometimes not needed. – Jean-François Fabre Mar 02 '17 at 20:41
  • @Jean-FrançoisFabre It's not always faster, to further optimize it one use a bound method `dctsetdefault = dct.setdefault` and use that inside the loop! But the actual timing depends on the length of the list and the number of duplicate keys (maybe even on other stuff as well). If speed is a concern use `iteration_utilities.groupedby(lst, key=operator.itemgetter(0), keep=operator.itemgetter(1))` (but requires importing the `operator`-module and an external library). – MSeifert Mar 02 '17 at 20:46
1

Code agency at your service:

lst = [['4','apples'],['3','oranges'],['4','bananas'],['2','apples'],['2','pineapple'],['3','apples']]

result = {}
for item in lst:
    key = item[0]
    try:
        result[key].append(item[1])
    except:
        result[key] = [item[1]]

print(result)
# {'3': ['oranges', 'apples'], '2': ['apples', 'pineapple'], '4': ['apples', 'bananas']}

As stated by @Jean-Francois Fabre, this solutions is rather slow: 3,5 seconds bs 5.7 seconds for 100000 iterations with 3,5 being the solution with defaultdict.

Jan
  • 42,290
  • 8
  • 54
  • 79
  • @Jean-FrançoisFabre: You have a comparison? – Jan Mar 02 '17 at 20:28
  • yes and it's slower, as expected because of exceptions. You may want to work on bigger data to see that, but with existing data, I get 3,5 seconds bs 5.7 seconds for 100000 iterations with your solution. – Jean-François Fabre Mar 02 '17 at 20:38
  • @Jean-FrançoisFabre: Thanks for the hint, I'll update the answer to reflect your thoughts. – Jan Mar 02 '17 at 20:39
  • actually it's more like 1000000 iterations. Also you could directly unpack key & values instead of accessing by index. Maybe it slows down execution too. – Jean-François Fabre Mar 02 '17 at 20:43
0

Using collections.defaultdict:

result = defaultdict(list)
for key, value in [[4,apples],[3,oranges],[4,bananas],[2,apples],[2,pineapple],[3,apples]]:
    result[key].append(value)
Daniel
  • 42,087
  • 4
  • 55
  • 81
0

collections.defaultdict might be useful to you.

from collections import defaultdict


items =  [
    [4, "apples"],
    [3, "oranges"],
    [4, "bananas"],
    [2, "apples"],
    [2, "pineapple"],
    [3, "apples"]
]

mapping = defaultdict(list)
for number, name in items:
    mapping[number].append(name)

Examples of official document of defaultdict would be helpful to you.

https://docs.python.org/3/library/collections.html#defaultdict-examples

sangheestyle
  • 1,037
  • 2
  • 16
  • 28