I'll describe the motivation below, but the essential question: I'd like to be able to do something like this:
# THIS DOESN'T WORK
def foo(var1, var2):
d = {
'a': var1,
'b': var2 if var2 is not None, # SyntaxError
}
return d
>>> foo(3, 4)
{'a': 3, 'b': 4}
>>> foo(3, None)
{'a': 3}
This description doesn't work because you're not allowed to have dict (key, value)
pairs without a value. You have to do
{'b': var2 if var2 is not None else <some value>}
and what I want to do is have the 'b'
item excluded from the return dict completely.
There are various reasonably Pythonic ways to do this, but the ones I can think of all require you to iterate over a length-n iterable, where n is the number of arguments to foo
:
# This works
def foo(var1, var2):
mapping = [
('a', var1),
('b', var2),
]
d = {k: v for (k, v) in mapping if v is not None}
return d
# As does this
def foo(var1, var2):
d = {
'a': var1,
'b': var2,
}
for k, v in d.iteritems():
if v is None:
d.pop(k)
return d
This isn't expensive but it'd be nice to be able to build the dict in one operation. Can you build the dict in one operation?
The motivation, if you're interested: foo
actually calls a constructor MyObj(**d)
, and this constructor can take a variable number of arguments. However, initializing MyObj.b = None
is different from not initializing MyObj.b
. And no, I can't alter MyObj
:).
Update: Martijn Pieters' answer here basically says you can't; you either have to process a separate iterable, or add the key afterwards (which generalizes to a loop over all arguments). If that's still the case I'm happy for this question to be closed.