Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For loop is overwriting dictionary values in list [duplicate]

Issue

I've made a for loop reading the contents of a list however when assigning two values to a dictionary and then appending that output to a list, the next value overwrites everything in the list

Desired outcome

I want to append multiple dictionaries to a list so when I run a for loop and print everything related to 'ip' it will print all the values associated with the dictionary value 'ip'.

Code

device =  { 'ip': '', 'mac': '', 'username': 'admin', 'password': [], 'device type': '', }
listofdevices = []
def begin():
   file = open("outputfromterminal")
   contents = file.read()
   contents = contents.split(',')[1:]
   for x in contents:
     # do some text stripping
     x = x.split(' ')
     device['ip']=x[0]
     device['mac']=x[1]
     listofdevices.append(device)

Sample code

the 1st index of contents is:

x[0] = '10.10.10.1'
x[1] = 'aa:bb:cc:dd'

The 2nd index of contents is:

x[0] = '20.20.20.1'
x[1] = 'qq:ww:ee:ee:rr'

What actually happens

  listofdevices[0] 'ip': 20.20.20.1, 'mac': 'qq:ww:ee:ee:rr'
  listofdevices[1] 'ip': 20.20.20.1, 'mac': 'qq:ww:ee:ee:rr'
like image 664
Danny Watson Avatar asked Dec 18 '17 20:12

Danny Watson


2 Answers

Try this code. Each device was trying to edit the same copy of a dictionary.

listofdevices = []

def begin():
    with open("outputfromterminal", 'r') as f:
        contents = f.read().split(',')[1:]

    for line in contents:
        # do some text stripping
        line = line.split(' ')

        device =  { 'ip': line[0],
                    'mac': line[1],
                    'username': 'admin',
                    'password': [],
                    'device type': '',
                   }

        listofdevices.append(device)
like image 167
Myles Hollowed Avatar answered Nov 06 '22 07:11

Myles Hollowed


You are not creating a new dictionary object each time. You are simply mutating the same object within each iteration. Try deep copying the dictionary using the copy module. Then after obtaining this copy, mutate it and append to list:

import copy
device =  { 'ip': '', 'mac': '', 'username': 'admin', 'password': [], 'device type': '', }
listofdevices = []
def begin():
   file = open("outputfromterminal")
   contents = file.read()
   contents = contents.split(',')[1:]
   for x in contents:

     device = copy.deepcopy(device) #creates a deep copy of the values of previous dictionary.  
     #device now references a completely new object

     # do some text stripping
     x = x.split(' ')
     device['ip']=x[0]
     device['mac']=x[1]
     listofdevices.append(device)
like image 43
DemetriOS Avatar answered Nov 06 '22 05:11

DemetriOS