2

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.

Community
  • 1
  • 1
A.Wan
  • 1,818
  • 3
  • 21
  • 34

0 Answers0