Search code examples
pythondictionary-comprehension

list to dictionary comprehensions


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?


Solution

  • 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}