Is it possible to use the else
statement (and if yes, how?) in a dictcomp
?
It is not possible to use else
as part of the comprehension itself (see this) but at least in list
and set
comprehensions it is possible to use the conditional_expression
(see this).
An example for listcomp
is here.
My example code is:
converters = {"id": int}
rows = [{"id": "1", "name": "foo"}, {"id": "2", "name": "bar"}]
for row in rows:
row = {k: converters[k](v) if k in converters else k:v for k,v in row.items()}
print(row)
This does not work.
The weird part is that
row = {k: converters[k](v) if k in converters for k, v in row.items()}
does not work either, although it should be ok.
row = {k: converters[k](v) for k, v in row.items() if k in converters}
does work,but this is not the result I want.
row = {k: converters[k](v) for k, v in row.items() if k in converters else k:v}
should not work, as I pointed out above.
I know that I could bypass the problem by using two dictcomps, but I want to know why this does not work.
That's because the conditional applies for the value of the dictionary, not for the key value pair, i.e it is evaluated as:
row = {k: (converters[k](v) if k in converters else k:v) for k,v in row.items()}
and k:v
is not syntactically valid here, it's only valid inside a pair of curly brackets or in a function signature (so, you could place k:v
in brackets and fix the SyntaxError
but, that changes the end result).
The solution is to simply supply the value in the conditional since that is what changes:
row = {k: converters[k](v) if k in converters else v for k,v in row.items()}
Another option, of course, is to instead supply tuples to the dict
constructor:
row = dict((k, converters[k](v)) if k in converters else (k,v) for k,v in row.items())