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())