I have the following dict comprehension but I don't know how to convert it back to for loop.
Value = [1,2,3,4,5]
Key = ['a','b','c','a','c']
{k: [Value[i] for i in [j for j, x in enumerate(Key) if x == k]] for k in set(Key)}
I tried:
d1 = {}
for k in set(Key):
for i in [j for j, x in enumerate(Key) if x == k]:
d1[k].append(Value[i])
But this is clearly wrong. Thanks!
CodePudding user response:
I am not sure what Value
is previously declared as but the dict comprehension is equivalent to:
d1 = {}
for k in set(Key):
d1[k] = []
for i in [j for j, x in enumerate(Key) if x == k]:
d1[k].append(Value[i])
You need to set d1[k]
to an empty list first.
CodePudding user response:
You just need to create d1[k]
as a list.
for k in set(Key):
d1[k] = []
...
Although, the inner list comprehension is redundant: all it really does is rename j
to i
. You can unwrap it too:
for k in set(Key):
d1[k] = []
for i, x in enumerate(Key):
if x == k:
d1[k].append(Value[i])
That said, this whole thing is overcomplicated and can be done much more easily with zip
:
d1 = {}
for k, v in zip(Key, Value):
values = d1.setdefault(k, [])
values.append(v)
print(d1) # -> {'a': [1, 4], 'b': [2], 'c': [3, 5]}
Although, if Key
and Value
aren't guaranteed to be the same length, this may fail silently. To avoid that, in Python 3.10 you could use zip(Key, Value, strict=True)
, otherwise you could rework it to be for i, k in enumerate(Key) ... values.append(Values[i])
.
Note: In Python 3.7 , this solution preserves insertion order where yours doesn't due to the set
conversion.
CodePudding user response:
Consider the following code in the question:
{k: [Value[i] for i in [j for j, x in enumerate(Key) if x == k]] for k in set(Key)}
It might be a pretty great one-liner, but it's not immediately obvious to anyone what it does. In fact I spent a bit of time puzzling out how it works, and I still don't fully understand it yet.
In this case, I would suggest simplifying it, perhaps by splitting it over a few extra lines, just so that it's clearer for others and also for yourself what is going on. For example, consider the following example with defaultdict
, which is a subclass of dict
:
my_dict = defaultdict(list)
for k, v in zip(Key, Value):
my_dict[k].append(v)
Result of my_dict
, which again contains the same contents:
defaultdict(<class 'list'>, {'a': [1, 4], 'b': [2], 'c': [3, 5]})