user132520 user132520 - 1 year ago 63
Python Question

Modifying a dictionary contained within a list

I am currently writing some code that reads lines in from a text file. The line is split into 3 different segments, with the first segment being a user ID.

For example, one line would look like this:

11 490 5

I have a list with as many elements as there are users, where each element corresponds with a user (eg
stores data for the 5th user).

Each list element contains a dictionary of indefinite length, where the key is the second segment of the line, and the value is the third segment of the line.

The length of the dictionary (the number of key-value pairs) increases if the same user's ID occurs in another line. The idea is that when another line with the same user ID is encountered, the data from that line is appended to the dictionary in the list element that corresponds to that user.

For example, the above line would be stored in something like this:

exampleList[10] = {490:5}

and if the program read another line like this:
11 23 9

the list item would update itself to this:

exampleList[10] = {490:5, 23:9}

The way my program works is that it first collects the number of users, and then creates a list like this:

exampleList = [{}] * numberOfUsers

It then extracts the position of whitespace in the line using
, which is then used to extract the numbers through basic string operations.

That part works perfectly, but I'm unsure of how to update dictionaries within a list, namely appending new key-value pairs to the dictionary.

I've read about using a for loop here, but that won't work for me since that adds it to every dictionary in the cell instead of just appending it to the dictionary in a certain cell only.

Sample code:

oFile = open("file.txt", encoding = "ISO-8859-1")
text = oFile.readlines()
cL = [{}] * numOfUsers #imported from another method
for line in text:
a = [m.start() for m in re.finditer('\t', line)]
userID = int(line[0:a[0]])
uIDIndex = userID - 1

1 242 3
3 302 3
5 333 10
1 666 9

expected output:
[{242:3 , 666:9},{},{302:3},{},{333:10}]

actual output:
[{242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}]

For some reason, it populates all dictionaries in the list with all the values.

Answer Source

I'm not positive I understand your problem correctly but I was able to get the output you desired. Note that this solution completely ignores the fourth value in the list

import re
fileData = [] #data from file.txt parsed through regex

with open("file.txt") as f:
    for line in f:
        regExp = re.match(r"(\d+)\s+(\d+)\s(\d+)", line)  #extracts data from row in file
        fileData.append((int(, int(, int( #make 2-d list of data
maxIndex = max(fileData, key=lambda x: x[0])[0] #biggest index in the list (5 in this case)

finaList = [] #the list where your output will be stored
for i in range(1, maxIndex+1): #you example output showed a 1-indexed dict
    thisDict = {} #start with empty dict
    for item in fileData:
        if item[0] == i:
            thisDict[item[1]] = item[2] #for every item with same index as this dict, add new key-value to dict
    finaList.append(thisDict) #add this dict to output list

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download