简体   繁体   中英

How to create Python dictionary with multiple 'lists' for each key by reading from .txt file?

I have a large text file that looks like:

1   27  21  22
1   151 24  26
1   48  24  31
2   14  6   8
2   98  13  16
.
.
.

that I want to create a dictionary with. The first number of each list should be the key in the dictionary and should be in this format:

{1: [(27,21,22),(151,24,26),(48,24,31)],
 2: [(14,6,8),(98,13,16)]}

I have the following code (with total points being the largest number in the first column of the text file (ie largest key in dictionary)):

from collections import defaultdict

info = defaultdict(list)
filetxt = 'file.txt'
i = 1

with open(filetxt, 'r') as file:
    for i in range(1, num_cities + 1):
        info[i] = 0
    for line in file:
        splitLine = line.split()
        if info[int(splitLine[0])] == 0:
            info[int(splitLine[0])] = ([",".join(splitLine[1:])])
        else:
            info[int(splitLine[0])].append((",".join(splitLine[1:])))

which outputs

{1: ['27,21,22','151,24,26','48,24,31'],
 2: ['14,6,8','98,13,16']}

The reason I want to do this dictionary is because I want to run a for loop through each "inner list" of the dictionary for a given key:

for first, second, third, in dictionary:
   ....

I cannot do this with my current code because of the slightly different format of the dictionary (it expects 3 values in the for loop above, but receives more than 3), however it would work with the first dictionary format.

Can anyone suggest anyway to fix this?

result = {}
with open(filetxt, 'r') as f:
    for line in f:
        # split the read line based on whitespace
        idx, c1, c2, c3 = line.split()

        # setdefault will set default value, if the key doesn't exist and
        # return the value corresponding to the key. In this case, it returns a list and
        # you append all the three values as a tuple to it
        result.setdefault(idx, []).append((int(c1), int(c2), int(c3)))

Edit: Since you want to the key also to be an integer, you can map the int function over the split values, like this

        idx, c1, c2, c3 = map(int, line.split())
        result.setdefault(idx, []).append((c1, c2, c3))

You are converting your values back to comma separated strings, which you can't use in for first, second, third in data - so just leave them as a list splitLine[1:] (or convert to tuple ).
You don't need your initializing for loop with a defaultdict . You also don't need the conditional checks with defaultdict either.

Your code without the superfluous code:

with open(filetxt, 'r') as file:
    for line in file:
       splitLine = line.split()
       info[int(splitLine[0])].append(splitLine[1:])

One slight difference is if you want to operate on int s I would convert up front:

with open(filetxt, 'r') as file:
    for line in file:
       splitLine = list(map(int, line.split()))   # list wrapper for Py3
       info[splitLine[0]].append(splitLine[1:])

Actually in Py3, I would do:

       idx, *cs = map(int, line.split())
       info[idx].append(cs)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM