9

I am attempting to access a dictionary's values based on a list of keys I have. If the key is not present, I default to None. However, I am running into trouble when the value is an empty string ''. Please see the code below for my examples

dict = {} dict['key'] = '' test = dict.get('key') print(test) >> 

Above is as expected, and the empty string is printed. But now see what happens when I default the dict.get() function to None if the key is not present

dict = {} dict['key'] = '' test = dict.get('key') or None print(test) >> None 

Why does this happen? In the second example the key is present so my intuition says '' should be printed. How does Python apply the 'or' clause of that line of code?

Below is the actual code I'm using to access my dictionary. Note that many keys in the dictionary have '' as the value, hence my problem.

# build values list params = [] for col in cols: params.append(dict.get(col) or None) 

Is there a best solution someone can offer? My current solution is as follows but I don't think it's the cleanest option

# build values list params = [] for col in cols: if dict.get(col) is not None: params.append(dict.get(col)) else: params.append(None) 
5
  • 1
    as for the first question, empty strings are falsy in python, so the second option for the or operator is printed Commented May 11, 2016 at 14:20
  • 3
    You can simply use dict.get('key'). get already returns None if it can't find the key. Commented May 11, 2016 at 14:30
  • if dict.get(col) is not None: <use dict.get(col)> ; else: <use None which is the value of dict.get(col)> Really? Commented May 11, 2016 at 14:38
  • Yep that works, thank you. I disagree that it is a duplicate of the question linked as my question deals mostly with the behavior of the dict.get() function. Nonetheless glad this is solved. Commented May 11, 2016 at 14:49
  • 1
    To expand on @TadhgMcDonald-Jensen's comment, you really just want for col in cols: params.append(dict.get(col)). Or you could simplify further to make the code a one-liner with params = [dict.get(col) for col in cols], or if cols is huge and you really need that last ounce of performance, params = map(dict.get, cols) (wrap the map call in list if you're on Python 3 and need params to be a true list, not a lazy generator that can be iterated exactly once and then discarded). Side-note: Don't name your dict "dict" (or any other built-in name); name shadowing is bad. Commented May 11, 2016 at 16:12

3 Answers 3

21

You don't need or None at all. dict.get returns None by default when it can't find the provided key in the dictionary.

It's a good idea to consult the documentation in these cases:

get(key[, default])

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

Sign up to request clarification or add additional context in comments.

Comments

6

You can simply use the second argument of get.

dict.get(col, None) 

The second argument is the default for when it can't find the key. The or in that case takes the thing before the or if it is something, otherwise takes whatever is after the or.

2 Comments

Mind you, dict.get(col, None) is 100% identical to dict.get(col); the default argument for dict.get is already None, so passing it explicitly doesn't change behavior at all. Also, it doesn't really address the problem, which is that empty strings are falsy.
The default for .get's second argument is None, so OP needs neither the or nor to provide None as the second argument.
1

The issue is that the empty string is not considered True in python. for example take a look at this code.

>>> x = 1 if "" else 0 >>> y = 1 if True else 0 >>> z = 1 if False else 0 

The value of x and z will be 0 while the value for y will be 1.

dict.get() returns None by default 

or by using a defaultdict

2 Comments

dict.get() already returns None if the key isn't found, by default.
this would be easier explained with bool('') -> False and a link to the relevent documentation

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.