I have the following code snippet:
d = {1:2, 3:4, 5:6}
d1 = {k*2:v/2 for (k,v) in d.items()}
d2 = {k*2:v/2 for [k,v] in d.items()}
d3 = {k*2:v/2 for [k,v] in d.items() if [k,v] in d.items()}
print(d1)
print(d2)
print(d3)
this produces the following output:
{2: 1.0, 6: 2.0, 10: 3.0}
{2: 1.0, 6: 2.0, 10: 3.0}
{}
Dictionary comprehension of d1
makes sense as it checks for a tuple of form (k,v)
in d.items()
which is "kind of" list of tuples.
Dictionary comprehension of d2
should return {}
as the list [k,v]
isn't present in d.items()
which is verified in dictionary comprehension of d3
.
What is the difference between the in
inside the for
loop and using it outside?
From the for statement docs, for target_list in expression_list
assigns objects from expression_list
to target_list
on each iteration. Just as list assignment in a regular statement assigns values
>>> [x,y] = 100, 200
>>> x
100
>>> y
200
for [k,v] in d.items()
assigns the tuple values iterated by d.items()
to x
and y
. As a result, {k*2:v/2 for (k,v) in d.items()}
and {k*2:v/2 for [k,v] in d.items()}
are the same.
In your final case,
d3 = {k*2:v/2 for [k,v] in d.items() if [k,v] in d.items()}
The reason that d3
is empty is that the list
[k,v]
is not in d.items()
, which iterates tuples. But the tuple
k,v
is. Change the check and you get the full dictionary again
>>> d4 = {k*2:v/2 for [k,v] in d.items() if (k,v) in d.items()}
>>> d4
{2: 1.0, 6: 2.0, 10: 3.0}
A final word on assignment to a list, I was surprised that it is not a syntax error. In fact, when you do the assignment, you get a tuple not a list. I'm puzzled!
>>> z = [x,y] = (100,200)
>>> z
(100, 200)