I'm practicing some python syntax exercises and I decided to write a dictionary comprehension based on a similarly designed list comprehension. But while the later is OK, the former results in a syntax error.
This is my list comprehension..
>>> l = [z**z if z%2 else z for z in range(5)]
[0, 1, 2, 27, 4]
and this is my dictionary comprehension..
>>> d = {z:z**z if z%2 else z:z for z in range(5)}
^
SyntaxError: invalid syntax
is there a way to write a dictionary comprehension that is similar in design to my list comprehension?
You can just write
In [16]: d = {z:z**z if z%2 else z for z in range(5)}
In [17]: d
Out[17]: {0: 0, 1: 1, 2: 2, 3: 27, 4: 4}
which is easier to read if you supply parentheses:
In [18]: d = {z:(z**z if z%2 else z) for z in range(5)}
In [19]: d
Out[19]: {0: 0, 1: 1, 2: 2, 3: 27, 4: 4}
The enclosed part is a Python ternary expression for the value, not for the (key, value) pair.
@timgeb but what if he also wants to change the key too in the else?
(Let's assume we want z*10
.) In cases like this, you could write something like
In [24]: d = {(z*10 if z%2 else z):(z**z if z%2 else z) for z in range(5)}
In [25]: d
Out[25]: {0: 0, 10: 1, 4: 4, 2: 2, 30: 27}
but this is inefficient because z%2
is computed twice.
It is better to make use of the fact that the dict
constructor takes an iterable of two-element iterables:
In [26]: dict((z*10, z**z) if z%2 else (z, z) for z in range(5))
Out[26]: {0: 0, 10: 1, 4: 4, 2: 2, 30: 27}