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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With