Python get function adds

Question:

I was trying to read an example when i stumbled upon a form i couldn’t quite understand:

my_values = parse_qs("red=5&blue=0&green=", keep_blank_values=True)

opacity = my_values.get("opacity", [""])[0] or 0

The code was calling a dict i made and made a parameter for when the value is missing then added "[0] or 0" part to the code which i couldn’t understand how it works

So i tried to run the code asking for a key that wasn’t there to run the parameter and it gave me zero as an answer to my unidentified key

when i tried to run the same code without "[0] or 0" part it gave an empty list "[""]" for the unknown key and when i removed the "or 0" part the answer changed to just this ""

So what functionality is this? so i can read more about it?

Thanks in advance

Asked By: Yousef Yahia

||

Answers:

This is an occasional pattern used to handle falsy values and also non-existent keys in a dictionary. For instance,

>>> d1 = {"opacity": ""}
>>> d2 = {"opacity": None}
>>> d3 = {}
>>> d1.get("opacity") or 0
0
>>> d2.get("opacity") or 0
0
>>> d3.get("opacity") or 0
0

All 3 of them give you the same result without throwing a key error.

Answered By: BcK

Given my_values as you defined them, the following is its value-

{'red': ['5'], 'blue': ['0'], 'green': ['']}
>>> my_values.get("red", [""])
['5']
>>> my_values.get("red", [""])[0]
'5'
>>> my_values.get("opacity", [""])
[""]
>>> my_values.get("opacity", [""])[0]
""

So the expresion you want is probably my_values.get(color, [""])[0] or my_values.get(color, [None])[0], which will return None if the color is not found.

Answered By: Guy

the code some_dict.get("some_key", [""])[0] or 0 have 3 working parts, lets dissect them

First, lets start with the or part, or is a boolean operator (of the same name), and can also be looked at as the following function

def or_(a,b):
    if bool(a):
        return a
    else:
        return b 

(but unlike the function version it have the capability of short-circuit)

>>> 1 or 2
1
>>> 0 or 2
2
>>> "hello" or "world"
'hello'
>>> "" or "world"
'world'
>>> "hello" or 0
'hello'
>>> "" or 0
0

as for the short-circuit, it means that the second expression isn’t evaluated if the first is Truth

>>> 1 or 1/0 # no error here because 1/0 isn't evaluated
1
>>> 0 or 1/0
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    0 or 1/0
ZeroDivisionError: division by zero

The second part is the .get in some_dict.get("some_key", [""]), that is the same as some_dict["some_key"] but without the throwing KeyError on a missing key and instead returning the second argument (if given, None otherwise), your default value, that in this case is [""]

>>> some_dict = {"a":1,"b":2,"c":3}
>>> some_dict.get("a",32)
1
>>> some_dict.get("xxx",32)
32
>>> 

And finally the [0] and the end of some_dict.get("some_key", [""])[0], here there is an implicit assumption that whatever you get from the dict is something you can index, like a list, tuple, string, etc. and you want the first element of it, that is why the second argument for .get is a list with a single element, so even in the case when the key is missing, your default value is a list with a single element, so you get that at the end

>>> some_dict = {"a":[1,2,3],"b":[4,5],"c":[6]}
>>> some_dict.get("a",[""])
[1, 2, 3]
>>> some_dict.get("a",[""])[0]
1
>>> some_dict.get("xxx",[""])
['']
>>> some_dict.get("xxx",[""])[0]
''
>>> 

So with all that combined, then you get either the first element of the value for that key if it is truth or 0 if not or is missing

Answered By: Copperfield
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.