0

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

depperm
  • 10,606
  • 4
  • 43
  • 67
zelenov aleksey
  • 398
  • 4
  • 13

5 Answers5

3

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

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.

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
1

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()])
Dmitry
  • 2,026
  • 1
  • 18
  • 22
1

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]}
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
1

"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.

Victoria Stuart
  • 4,610
  • 2
  • 44
  • 37