Assign value to a dictionary variable that is optional

Asked

Viewed 1,094 times

18

I have a function where one of the parameters is a dictionary, but it’s optional.

I need to assign a value in this dictionary, but take into account the case where this parameter is not filled in.

The following solution uses two lines for this:

def uma_funcao(um_dict=None):
    um_dict = um_dict or {}
    um_dict['uma_chave'] = True

I believe there is one more way pythonic to do so in one line. It is possible?

3 answers

14

No, I believe that the form you have presented is minimal. I cannot talk about Python 3, because I have no experience.

(Negative responses are complicated, but I have no supporting evidence, except for the absence of evidence to the contrary...)


Updating: as 3 people have already posted the same incorrect answer, I will point it out here to avoid future identical answers.

>>> def uma_funcao(um_dict={}):
...   um_dict['uma_chave'] = True
...   return um_dict
...
>>> x = uma_funcao()
>>> x['teste'] = True
>>> y = uma_funcao()
>>> y
{'uma_chave': True, 'teste': True}

As you can see, you shouldn’t use a changeable value as standard parameter of a function. The expression {} creates an object before to be used as a parameter, so that every call to uma_funcao without passing parameters will use the same dict. As rarely this is the desired behavior, there is no option but the use of None followed by a test, as in the original question code.

Another way that occurred to me, very common in languages like C, was to combine attribution with use in a single expression:

(um_dict = um_dict or {})['uma_chave'] = True

However this is not allowed by the Python syntax (2 at least; if something like this has been added in future versions, it is not to my knowledge).

2

This is no good?

def uma_funcao(um_dict = {}):
  um_dict['uma_chave'] = True
  return um_dict

I don’t understand why to assign None rather than assign {} directly. If there is any reason for this, please go into more detail.

  • 3

    The reason is that the same dict will be used in every invocation of uma_funcao [no arguments], but the expected behavior (intuitive until) would be that a new Dict be created at each invocation.

2

One way around the problem presented by @mgibsonbr is to return a copy of the dictionary instead:

def uma_funcao(um_dict={}):
    um_dict['uma_chave'] = True
    return um_dict.copy()

Note that, if um_dict be passed, it will continue to be modified:

>>> def uma_funcao(um_dict={}):
...   um_dict['uma_chave'] = True
...   return um_dict.copy()
...
>>> x = uma_funcao()
>>> x['teste'] = True
>>> y = uma_funcao()
>>> y
{'uma_chave': True}
>>> d = {'uma_chave': False}
>>> z = uma_funcao(d)
>>> z
{'uma_chave': True}
>>> d
{'uma_chave': True}

It is still possible to do everything in a single line, although it is far from being considered something pythonic:

def uma_funcao(um_dict={}):
    return um_dict.update({'uma_chave': True}) or um_dict.copy()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.