Reputation: 398
I'm trying to update values in dictionary of lists EX: I have a dictionary input:
d={0: [0,1], 1:[1],2:[2],3:[3]}
and pair [0,2]
and I want to replace every 0 in dict with 0,2 and increase each value >2 by 1, so here the expected output:
{0: [0,2,1], 1:[1],2:[2],3:[4]}
I tried to iterate over all values, but it didn't make the trick properly
def update_dict(_dict,_pair):
for i in range(len(_dict.keys())):
for j in range(len(_dict.values()[i])):
if dict[i][j]==_pair[0]:
dict[i][j].remove(_pair[0])
dict[i].append(_pair)
return _dict
How do I achieve that? Thanks in advance for any help
Upvotes: 0
Views: 454
Reputation: 5072
"How to update values within lists within a dictionary?" is a good question. Suppose I have a dictionary of lists and I want to change a value within one of those lists.
import copy
i = 1
input_sentence_dict = {i: []}
input_sentence_dict[1] = "['I', 'have', 'a', 'gift', 'for', 'Carmine', '.']"
input_sentence_dict[2] = "['I', 'gave', 'it', 'to', 'her', '.']"
import pprint
pp = pprint.PrettyPrinter(indent=4)
print('input_sentence_dict:')
pp.pprint(input_sentence_dict)
'''
input_sentence_dict:
{ 1: ['I', 'have', 'a', 'gift', 'for', 'Carmine', '.'],
2: ['I', 'gave', 'it', 'to', 'her', '.']}
'''
output_sentence_dict = copy.deepcopy(input_sentence_dict)
print('output_sentence_dict:')
pp.pprint(output_sentence_dict)
'''
output_sentence_dict:
{ 1: ['I', 'have', 'a', 'gift', 'for', 'Carmine', '.'],
2: ['I', 'gave', 'it', 'to', 'her', '.']}
'''
# example of indexing:
print(output_sentence_dict[2][1:3])
# ['gave', 'it']
Through indexing, you can easily change a value within one of those lists. For example:
output_sentence_dict[2][2] = 'a book'
pp.pprint(output_sentence_dict)
'''
{ 1: ['I', 'have', 'a', 'gift', 'for', 'Carmine', '.'],
2: ['I', 'gave', 'a book', 'to', 'her', '.']}
'''
Note. If you simply copy a dictionary (e.g. dict2 = dict1
), edits to one affects the other. You need to "deepcopy" the source dictionary to ensure that you work on a truly different object, leaving the source object unperturbed.
import copy
dict2 = copy.deepcopy(dict1)
You may then edit dict2
, leaving dict1
unaltered.
This is well-described in this StackOverflow thread: How to copy a dictionary and only edit the copy
Working with "shallow copies," e.g.
dict2 = dict1
# or
dict2 = dict(dict1)
will result in silent errors. In the example above, if you do not use copy.deepcopy(dict)
, changes made to output_sentence_dict
will also silently propagate to input_sentence_dict
.
Upvotes: 1
Reputation: 92854
Another alternative solution:
d={0: [0,1], 1:[1],2:[2],3:[3]}
for k,a in d.items():
for key, digit in enumerate(a):
if digit == 0: a[key:key+1] = [0,2]
if digit > 2: a[key] += 1
print(d)
The output:
{0: [0, 2, 1], 1: [1], 2: [2], 3: [4]}
Upvotes: 1
Reputation: 2096
There is a large number of solutions. For example:
d = {0: [0,1], 1:[1],2:[2],3:[3]}
new_d = dict()
for k in d:
new_d[k] = sum([i == 0 and [0, 2] or i > 2 and \
[i + 1] or [i] for i in d[k]], [])
or
d = {0: [0,1], 1:[1],2:[2],3:[3]}
new_d = dict([(k, sum([i == 0 and [0, 2] or i > 2 \
and [i + 1] or [i] for i in v], [])) for k, v in d.items()])
Upvotes: 1
Reputation: 81594
And if you still want to use a dictionary, this will do:
d = {0: [0,1], 1:[1],2:[2],3:[3]}
for k, li in d.items():
for i, v in enumerate(li[:]):
if v == 0:
li.insert(i + 1, 2)
elif v > 2:
d[k][i] += 1
print(d)
# {0: [0, 2, 1], 1: [1], 2: [2], 3: [4]}
Just keep in mind that the keys order is not guaranteed.
Upvotes: 1
Reputation: 1121476
You don't need a dictionary here, you want a list; you have an ordered series of keys starting at 0, indices of a list would more efficiently serve that need:
l = [[0,1], [1], [2], [3]]
You can produce the desired output:
for i, nested in enumerate(l):
# replace all 0 values with 1, 2
while 0 in nested:
zero_index = nested.index(0)
nested[zero_index:zero_index + 1] = [1, 2]
# increment values in the nested list if the index is over 2:
if i > 2:
nested[:] = [v + 1 for v in nested]
This alters the original nested lists in-place.
Upvotes: 3