Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
349 views
in Technique[技术] by (71.8m points)

python - dict.get() method returns a pointer

Let's say I have this code:

my_dict = {}
default_value = {'surname': '', 'age': 0}

# get info about john, or a default dict
item = my_dict.get('john', default_value)

# edit the data
item[surname] = 'smith'
item[age] = 68

my_dict['john'] = item

The problem becomes clear, if we now check the value of default_value:

>>> default_value
{'age': 68, 'surname': 'smith'}

It is obvious, that my_dict.get() did not return the value of default_value, but a pointer (?) to it.

The problem could be worked around by changing the code to:

item = my_dict.get('john', {'surname': '', 'age': 0})

but that doesn't seem to be a nice way to do it. Any ideas, comments?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
item = my_dict.get('john', default_value.copy())

You're always passing a reference in Python.

This doesn't matter for immutable objects like str, int, tuple, etc. since you can't change them, only point a name at a different object, but it does for mutable objects like list, set, and dict. You need to get used to this and always keep it in mind.

Edit: Zach Bloom and Jonathan Sternberg both point out methods you can use to avoid the call to copy on every lookup. You should use either the defaultdict method, something like Jonathan's first method, or:

def my_dict_get(key):
    try:
        item = my_dict[key]
    except KeyError:
        item = default_value.copy()

This will be faster than if when the key nearly always already exists in my_dict, if the dict is large. You don't have to wrap it in a function but you probably don't want those four lines every time you access my_dict.

See Jonathan's answer for timings with a small dict. The get method performs poorly at all sizes I tested, but the try method does better at large sizes.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...