Hami
Hami

Reputation: 13

All lists get overwritten in Python

I'm trying to to create a list, where all words in this function are saved and also the line number. I think the code is done, but every time a list inside it is the same than another list, all the lists got overwritten.

This is the code:

#Python 3.5X

import re

file = open(".\cross.txt", 'r')

def search(s):
    find1 = ''
    find2 = ''
    find3 = ''

    dic = {}
    pattern = re.compile(r"([a-zA-z_]*)[\s.=(]*([a-zA-Z_]*)[\s.=(]*([a-zA-Z_]*)")

    for line, i in enumerate(s.readlines()):
        result = pattern.search(i)
        find1 = ''
        find2 = ''
        find3 = ''
        find1 = result.group(1)
        find2 = result.group(2)
        find3 = result.group(3)
        y=[line]

        if find1 in dic.keys():
            tmp=dic.get(find1)
            tmp.append(line)
            dic[find1] = tmp
        else:
            dic[find1] = y

        if find2 in dic.keys():
            tmp=dic.get(find2)
            tmp.append(line)
            dic[find2] = tmp
        else:
            dic[find2] = y

        if find3 in dic.keys():
            tmp=dic.get(find3)
            tmp.append(line)
            dic[find3] = tmp
        else:
            dic[find3] = y

    return dic

print(search(file))

file.close()

Input:

def readin (file):
 in_file = open(file,"r")
 text = in_file.read()
 in_file.close()
 return text

Output

{'': [3, 4], 'text': [2, 4], 'file': [0, 1], 'close': [3, 4], 'read': [2, 4], 'in_file': [1, 2, 3], 'def': [0, 1], 'readin': [0, 1], 'return': [4], 'open': [1, 2, 3]}

For example, open is only in line 1, but it gets overwritten.

EDIT:

I try to find all the words inside the input. So for the first line I'm looking for "def" "readin" "file". Now the algorithm write this keywords into a dictionary with the line where it appears (0 in this case).

Now it checks the next line -> "in_file" "open" "file". The dictionary should now contain def:[0], readin: [0], in_file:[1], file: [0,1], open: [1]. The problem is, it also adds [1[] to def, because if I'm looking for file, i get back [0] and he changes all keywords which have value [0] to [0,1]

Minimal example:

l[x] = [0]
l[y] = [0]
new_list = [1]
l[x].append(new_list)

Now l[y] and l[x] are [0,1], but only l[x] should be.

Upvotes: 0

Views: 169

Answers (1)

Shasha99
Shasha99

Reputation: 1916

Consider the case when loop executes for the first time. i.e. for the first line of the file:

  • Suppose your regular expression gave you three values a,b and c and you stored them in find1='a', find2='b' and find3='c'.
  • Now since the dictionary would be empty initially, So all three else parts will execute:

dic['a'] = y, dic['b'] = y, dic['c'] = y

  • Now if you remember about the memory model of python, it works on referencing system. Since y is a reference referring to list [1], all the elements dic['a'], dic['b'] and dic['c'] along with y are referring to the same list:

dic['a'] = dic['b'] = dic['c'] = y = [1]


Now consider the case when loop executes for the second time. i.e. for the second line of the file:

  • Suppose your regular expression gave you three values a,d and e and you stored them in find1='a', find2='d' and find3='e'.
  • Now since 'a' is already present in dictionary, the if part of first condition if find1 in dic.keys(): will work and it will append 2 to the existing list:

dic['a'] = [1,2]

  • Now since dic['b'] and dic['c'] are also referring to the same list, the content of dic['b'] and dic['c'] will be same as of dic['a'].

dic['a'] = dic['b'] = dic['c'] = [1,2]

  • Now since d and e are not present in dict, So the same story will be repeated for key d and e:

dic['d'] = dic['e'] = y = [2]

Solution:

rather than writing y = [line] and assigning y to dic[find1], dic[find2] and dic[find3] , assign the list directly:

dic[find1] = [line]
dic[find2] = [line]
dic[find3] = [line]

This way you will be creating three individual lists.

Upvotes: 1

Related Questions