-2

My question is : I have a function in python which takes a dictionary and a string as input. This dictionary has strings as keys as lists as values. In function dictionaries lists are changed - entries removed as they are used until first empty list in values is hit. For one run it works well, but when this function is in a for loop changing only input string and using the very same dictionary, with each iteration original input dictionary is changed. This is despite in function by the first step I create a new dictionary setting it equal to input and make all changes on that new dictionary. Could you give me a hint of what is wrong? Why original dictionary is affected? Also I got the same when I create a new list in for loop before function and pass this new list as input.

Here is an actual code :

#reading an input file 
x=open('graph .txt')
data=[line.strip() for line in x.readlines()]

gr=[s.split(' -> ') for s in data]

#creating a graph 
graph={}

for i in gr:
    graph[i[0]]=list(i[1])

for val in graph.values():
    if ',' in val:
        val = val.remove(',')
cycle=[]

nums=graph.keys()

# function changing dictionary 
def path(start,graph):
    cycle=[]
    graph111=graph
    cycle.append(start)
    while graph111[start]!=[]:
        move=graph111[start]
        if move==[]:
            break
        if len(move)>1:
            n=''.join(move[0])
            start=n
            cycle.append(n)
        else:
             p=''.join(move)
             start=p
             cycle.append(p)
        move.remove(move[0])
    return ('->'.join(cycle))
# for loop:
for num in nums:
    c=path(num,graph)
    cycles.append(c) 

input looks like this:

 0 -> 3
 1 -> 0
 2 -> 1,6
 3 -> 2
 4 -> 2
 5 -> 4
 6 -> 5,8
 7 -> 9
 8 -> 7
 9 -> 6

2 Answers2

1

You are not creating a new list or dictionary by an assignment in python:

>>> a=[1,2,3]
>>> b=a
>>> b[1]=5
>>> b
[1, 5, 3]
>>> a
[1, 5, 3]

To copy a list, you can use the slice notation:

>>> c=a[:]
>>> c
[1, 5, 3]
>>> a[1]=10
>>> a
[1, 10, 3]
>>> c
[1, 5, 3]

For dictionaries, see Deep copy of a dict in python. For more complex data types and general hints, see https://docs.python.org/2/library/copy.html

Community
  • 1
  • 1
Jasper
  • 3,939
  • 1
  • 18
  • 35
1

Without actual code it is difficult to understand what's going on in your question, but let me make a guess: you have something like this:

def do_smth(dc):
    new_dict = dc
    new_dict['haha']='hohoho'

this_dict={}
do_smth(this_dict)

Then you see that this_dict has been changed. This is because you pass a reference to this_dict when invoke your function and thus your function is able to modify this_dict. Note also, that assignment does not make a copy, so new_dict = ds does not help you. You have to write new_dict = ds.copy() to make a copy. Moreover, if your dictionary has other mutable objects as values, .copy() will not be enough: you'll need to use copy.deepcopy() instead, see this question.

You can read the details here (in Russian).

Community
  • 1
  • 1
Ilya V. Schurov
  • 7,687
  • 2
  • 40
  • 78