Home > Software design >  Alternative way to use setdefault() using dictionary comprehension?
Alternative way to use setdefault() using dictionary comprehension?

Time:02-19

I have a nested dictionary that was created from a nested list where the first item in the nested list would be the outer key and outer value would be a dictionary which is the next two items. The following code is working great using the two setdefault() functions because it just adds to the nested dictionary when it sees a duplicate key of the outer. I was just wondering how you could do this same logic using dictionary comprehension?

dict1 = {}
list1 = [[1, 2, 6],
         [1, 3, 7],
         [2, 5, 8],
         [2, 8, 9]]
    
for i in list1:
    dict1.setdefault(i[0], {}).setdefault(i[1], i[2])

"""
OUTPUT: 1 {2: 6, 3: 7} 
        2 {5: 8, 8: 9}
"""

CodePudding user response:

I actually tried to achieve that result and failed.
The comprehension overwrites the new entries.

After, giving this idea a look, I found a similar post in which it is stated it is not possible:
https://stackoverflow.com/questions/11276473/append-to-a-dict-of-lists-with-a-dict-comprehension

I believe Amber's answer best sumarizes what the conclusion with my failed attempt with dict comprehensions:

No - dict comprehensions are designed to generate non-overlapping keys with each iteration; they don't support aggregation. For this particular use case, a loop is the proper way to accomplish the task efficiently (in linear time)

CodePudding user response:

Use the loop because it's very readable and efficient. Not all code has to be a one-liner.

Having said that, it's possible. It abuses syntax, extremely unreadable, inefficient, and generally just plain bad code (don't do it!)

out = {k: dict(v) for k,v in [g for g in [{}] if not 
                              any(g.setdefault(key, []).append(v) 
                                  for key, *v in list1)][0].items()}

Output:

{1: {2: 6, 3: 7}, 2: {5: 8, 8: 9}}
  • Related