Getting Reference to a Dictionary Value

How to reference a dict object?

As others have pointed out, this is not really possible in Python, it doesn't have C++ style references. The closest you can get is if your dictionary value is mutable, then you can mutate it outside and it will be reflected inside the dictionary (because you're mutating the same object as the object stored in the dictionary). This is a simple demonstration:

>>> d = {'1': [1, 2, 3] }
>>> d
{'1': [1, 2, 3]}
>>> x = d['1']
>>> x.append(4)
>>> d
{'1': [1, 2, 3, 4]}

But in general, this is a bad pattern. Don't do this if you can avoid it, it makes it really hard to reason about what's inside the dictionary. If you wanna change something in there, pass the key around. That's what you want.

Getting reference to a Dictionary value

You can't do it in a single move except by calling a function with an inout parameter, as you've already shown. Otherwise you cannot take a "reference" to a value type in Swift. The normal way is the old-fashioned, simple way, one step at a time: you pull out the inner dictionary, change it, and put it back again:

let key = "101"
var d = ["101": [1: "value1"]]
if var d2 = d[key] {
d2[1] = "value2"
d[key] = d2
}

It's boring but reliable.

dict.get() method returns a pointer

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.

Can I reference a dict value on dict creation?

Yes and No! You can use f-strings (available in Python-3.6+) to automatically format strings based on already available variables which in this case can be netdev["ipv6"]["prefix"]. If You're not aware of the value of netdev["ipv6"]["prefix"] before creating the dictionary there will be no way to do this on the fly, (at least in Cpyhon implementation or in general at Python-level). However, there might be some hacks to create a custom dictionary which re-formats the value of the intended keys as is mentioned here: Can you set a dictionary value dependant on another dictionary entry?.

PREFIX = previously_defined_prefix
net_dev = {
"link_name": "eth0",
"ipv4": {
"address": "10.80.0.1",
"mask": "255.255.255.0",
},
"ipv6": {
"prefix": PREFIX,
"addr": f"{PREFIX}1234:1",
"mask": "64",
"prefix_range": "2001:db8:0:100::",
}
}

In this case PREFIX is a variable defined in the same name space as the net_dev dictionary.

In you're using 3.6- versions instead of f-string approach you can simple use str.format() or just + operator:

PREFIX = previously_defined_prefix
net_dev = {
"link_name": "eth0",
"ipv4": {
"address": "10.80.0.1",
"mask": "255.255.255.0",
},
"ipv6": {
"prefix": PREFIX,
"addr": "{}1234:1".format(PREFIX), # PREFIX + "1234:1"
"mask": "64",
"prefix_range": "2001:db8:0:100::",
}
}

How to reference a specific part of a dictionary in Python

Dictionary values are looked up by their keys using [], not ..

Now, the trick is that the movies key points to a list. So you need to mix two kinds of indexing that both use []: dictionary indexing, which is by key, and list indexing, which is by position in the list (starting at 0).

Ultimately, you want to do this:

score = resultOne['movies'][0]['meterScore']
^ ^ ^
| | |
lookup in outer dict | |
first item in list |
lookup in inner dict

String by value; Dictionary by reference?

In Python, everything is by reference; This is different from C, variable is not a box. The assignment is actually a binding.

str1 = "hello"
str2 = str1

Both str1 and str2 reference to "hello", but string in Python is immutable, so modifying str2, would creating a new binding, and hence do not affect the value of str1

str2 = "hack"
# here str1 will still reference to "hello" object

Dict works the same:

d1 = {"name": "Tom"}
d2 = d1

d2 and d1 will reference the same object. If change d2 to a new value do not affect the value of d1; But instead, if we only modify d2 in place, like d2['age'] = 20, the value of d1 would be changed since they share the same object.

d2 = {"name": "Hack"}
# the value of d1 does not change

Luciano Ramalho summarized it in Fluent Python, Chapter 8, Variables Are Not Boxes section

To understand an assignment in Python, always read the righthand side first: that’s where the object is created or retrieved. After that, the variable on the left is bound to the object, like a label stuck to it. Just forget about the boxes.



Related Topics



Leave a reply



Submit