Python append to a value in dictionary - python

I have a following dictionary:
d = {'key':{'key2':[]}}
Is there any way to append to d['key']?
I want to get:
d = {'key':{'key2':[], 'key3':[]}}
d['key'] = ['key3'] apparently does not produce the desired outcome..
I know I can do
d = {'key': [{'key2': []}]}
and then append to d['key'] in a loop, but I am trying to avoid that..

You're looking for
d['key']['key3'] = []

Alternate solution.
d['key'].update({'key3':[]})

Since d["key"] is a dictionary, you can set keys in this dictionary as usual:
e = d["key"]
e["key3"] = []
or simply
d["key"]["key3"] = []

Why not trying:
d['key']['key3'] = []
That should work.

Related

Adding a key to a dictionary where the values are lists In Python

I want to add the variable key to the dictionary as a key, as well as add a value to a list. Is this the right way of going about this?
dict = {}
key = 'hold'
value = 'holdtwo'
value_two = 'holdthree'
dict[key].append(value)
dict[key].append(value_two)
You can use dedfaultdict to achieve this
from collections import defaultdict
dictionary = defaultdict(list)
key = 'hold'
value = 'holdtwo'
value_two = 'holdthree'
dictionary[key].append(value)
dictionary[key].append(value_two)
Don't use use keywords as variables!
dict = {} # dict is a keyword
Your asking for problems with it!
dict1 = {}
dict1['key'] = ['hold','hold2','hold3']
dict1['key'].append('hold4')
or a more extensive and larger variation on holding stuff (example):
dict1 = {}
keys = ['key1', 'key2', 'key3']
for key1 in keys:
dict1[key1] = []
vals = [1,2,3,4,5,6,7,8,9,10] #Just some values to store in the dicts
iKey = 1 #iKey is just an offset to show the differences between keys
for key2 in dict1:
iKey = iKey + 5
for val in vals:
dict[key2].append(iKey*val)
Loads of options.
Solved!
If I want to put in a new key that has an empty list, I use:
new_key = 'something'
dict[new_key] = []
If I want to add a value to an existing key's list:
value = 'something else'
dict[new_key].append(value)
This seems to work just fine with variables as keys.

How to convert each items of list into a dictionary?

Here I have a list like this.
ls = ['Small:u', 'Small:o']
What I want is to create a dictionary of each list items like this.
dict1 = {'Small':'u'}
dict2 = {'Small':'o'}
How can I do it ? Is it possible?
>>> x = [dict([pair.split(":", 1)]) for pair in ['Small:u', 'Small:o']]
>>> x
[{'Small': 'u'}, {'Small': 'o'}]
Yes, it is possible, but one thing I'm not sure whether is possible (or a good idea at all) is to programmatically assign variable names to new dictionaries, so instead the easier way is to create a dictionary of dictionaries:
dic_of_dics = {}
for index, item in enumerate(ls):
i, j = item.split(':')
dic_of_dics[f'dict{index}'] = {i : j}
This is another way:
ls = ['Small:u', 'Small:o']
dict_list = []
for i in ls:
k, v = i.split(':')
dict_list.append({k: v})
print(dict_list)
print(dict_list[1].values())
Perhaps with minimal line:
ls = ['Small:u', 'Small:o']
dict_list = map(lambda x:dict([x.split(':')]), ls)
# for python3: print(list(dict_list))
# for Python2: print(dict_list)
Explanation: I am using map function to convert the list of string to list of lists. Then I am passing it through dict(to convert them to dictionary).

One liner if an index doesnt exists

For a lot of objects before calling .append() I do something like:
if not d.get('turns'):
d['turns'] = []
Is there a oneliner in Python to do this?
After some answers, here's my kind of code:
d = json.loads(str(self.data))
if not d.get('turns'):
d['turns'] = []
d['turns'].append({
'date': time_turn,
'data': data
})
You can use defaultdict:
from collections import defaultdict
d = defaultdict(list)
d['turns'] # []
Other option is to use setdefault:
d.setdefault('turns', []) # []
d.setdefault('turns', 'foo') # []
UPDATE Given the full code you could either write
d = defaultdict(list, json.loads(str(self.data)))
d['turns'].append({'date': time_turn, 'data': data})
or
d = json.loads(str(self.data))
d.setdefault('turns', []).append({'date': time_turn, 'data': data})
Is there a oneliner in Python to do this?
Yes
d.setdefault('turns', [])
Demo:
>>> d = {}
>>> d.setdefault('turns', [])
[] # the inserted value is also returned
>>> d
{'turns': []}
If the key is found, setdefault behaves like get:
>>> d['turns'].append(1)
>>> d.setdefault('turns', 'irrelevant')
[1]
depending on if the get is standard, it likely has the option to specify a default return if the item is not found, so
d.get('turns', [])
will give you the value if it exists, or [] if it doesn't.
Well, you can "oneline" it using :
d['turns'] = [] if not d.get('turns')

Making a list of a "master" dictionary

I have a prototype dictionary that i want to use as a basis for appending to a list.
I want to change 1 or more values in the dictionary then capture it as an element of a list.
My question is this; is there any other recommended method for doing this short of using deepcopy().
I know this doesn't work properly:
l = []
d = {}
d['key'] = 4
l.append(d)
d['key'] = 5
l.append(d)
it gives:
l = [{'key': 5}, {'key': 5}]
it also didn't seem to work using a simply copy()
You are appending a reference to the same object to both lists, so when you change the value of "key", you change it in both lists. You need to make a copy of the dictionary before appending if you want a separate reference, using the dict.copy function:
l = []
d = {}
d['key'] = 4
l.append(d.copy())
d['key'] = 5
l.append(d.copy())
If you need a deep copy, you can use the copy library:
import copy
l = []
d = {}
d['key'] = 4
l.append(copy.deepcopy(d))
d['key'] = 5
l.append(copy.deepcopy(d))
copy should work.
l = []
d = {}
d['key'] = 4
l.append(d)
d = d.copy()
d['key'] = 5
l.append(d)
Result:
[{'key': 4}, {'key': 5}]

Deleting multiple items in a dict

I've searched around for the error it gives me, but I don't understand that quite well. They did something with for k, v in dbdata.items, but that didn't work for me neither, it gives me other errors.
Well, I want is to delete multiple items.
tskinspath = ['1', '2']
#
dbdata = {}
dbdata['test'] = {}
dbdata['test']['skins_t'] = {}
# Adds the items
dbdata['test']['skins_t']['1'] = 1
dbdata['test']['skins_t']['2'] = 0
dbdata['test']['skins_t']['3'] = 0
dbdata['test']['skins_t']['4'] = 0
# This doesn't work
for item in dbdata["test"]["skins_t"]:
if item not in tskinspath:
if dbdata["test"]["skins_t"][item] == 0:
del dbdata["test"]["skins_t"][item]
# exceptions.RunetimeError: dictonary changed size during iteration
Instead of iterating over the dictionary, iterate over dict.items():
for key, value in dbdata["test"]["skins_t"].items():
if key not in tskinspath:
if value == 0:
del dbdata["test"]["skins_t"][key]
On py3.x use list(dbdata["test"]["skins_t"].items()).
Alternative:
to_be_deleted = []
for key, value in dbdata["test"]["skins_t"].iteritems():
if key not in tskinspath:
if value == 0:
to_be_deleted.append(key)
for k in to_be_deleted:
del dbdata["test"]["skins_t"][k]
The error message says it: you shouldn't modify the dictionary that you are iterating over. Try
for item in set(dbdata['test']['skins_t']):
...
This way you are iterating over a set that contains all keys from dbdata['test']['skins_t'].
As the question details is way aside from the question, If you are looking for a solution that deletes multiple keys from a given dict use this snippet
[s.pop(k) for k in list(s.keys()) if k not in keep]
Additionally, you can create a new dict via comprehension.
new_dict = { k: old_dict[k] for k in keep }

Categories