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
Tintcolor Not Changing for UIbarbuttonitem for .Normal Stage in Case of iOS 13.2
Cannot Authenticate User for Aws Appsync with Swift Sdk
Inmemory Realm Threading in Swift
Can Not Get Correct Position of View in Swiftui
Error Domain=Nscocoaerrordomain Code=3840 "Invalid Value Around Character 0
Secidentity + Force Cast Violation: Force Casts Should Be Avoided. (Force_Cast)
Flattened Objects in JSON File to Nested Object Structure in Swift
Show Status Bar Only for iPhone X
How to Make First Responder in Swiftui Macos
Using a Timer in The Background Thread to Update UI
How to Synchronize Access to a Property That Has Didset
Swiftui: Make Remaining Area of List Item Detect Clicks
Do Not Copy Swift Libraries with Xcode 8
Realm Write Transaction Failing, Despite Being in Transaction