I'm new to Python and trying to build a data dictionary from a csv. I don't have a lot of flexibility to change the csv. I'm not sure if it would be easier (or even possible) to use a list as a value in a data dictionary, and then access a specific value in that list with some kind of index, or if I should import the data to have an additional key with only a float as the value.
Here's a sample of the structure in a csv:
Tester = [[1, 1, 3, 1, 10, 5, 10],
[1, 2, 3, 7, 5, 3, 8 ],
[1, 4, 5, 9, 7, 2, 8 ],
[2, 1, 2, 0, 0, 0, 0 ],
[2, 3, 5, 6, 4, 3, 2 ],
[2, 5, 6, 7, 10, 4, 4 ],]
I'm not sure how to produce this dictionary, with four keys:
(1, 1, 3, 1) = 1
(1, 1, 3, 2) = 10
(1, 1, 3, 3) = 5
(1, 1, 3, 4) = 10
(1, 2, 3, 1) = 7
(1, 2, 3, 2) = 5
(1, 2, 3, 3) = 3
(1, 2, 3, 4) = 8
(1, 4, 5, 1) = 9
(1, 4, 5, 2) = 7
...
Currently, I'm instead using a list as the value and getting the following output. I could leave the output as is, but then I'm getting a value error. Or, I could try to produce the output above, but I'm not sure how to do that. What this actually represents mathematically is a variable with four subscripts, so I'm not sure what the best practice would be here.
# Import libraries
from gurobipy import *
import csv
from math import *
import numpy as np
from random import *
import time
# arc capacity
capacityatest = open('C:/Users/Emma/Documents/2021-2022/Thesis/Data/tester.csv', 'r')
csv_capacityatest = csv.reader(capacityatest)
mydict_capacityatest = {}
for row in csv_capacityatest:
mydict_capacityatest[(row[0], row[1],row[2])] = list(row[3:7])
print(mydict_capacityatest)
arc, capacityatest = multidict(mydict_capacityatest)
{('1', '1', '3'): ['1', '10', '5', '10'], ('1', '2', '3'): ['7', '5', '3', '8'], ('1', '4', '5'): ['9', '7', '2', '8'], ('1', '7', '10'): ['9', '9', '4', '5'], ('1', '11', '12'): ['3', '4', '4', '7'], ('2', '1', '2'): ['0', '0', '0', '0'], ('2', '3', '5'): ['6', '4', '3', '2'], ('2', '5', '6'): ['7', '10', '4', '4'], ('2', '9', '10'): ['3', '2', '1', '7']}
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-b7e72ced1492> in <module>
15 print(mydict_capacityatest)
16
---> 17 arc, capacityatest = multidict(mydict_capacityatest)
ValueError: too many values to unpack (expected 2)
CodePudding user response:
When you're iterating over each row, also iterate over the elements 3 onwards (row[3:]
). You can use the enumerate()
function with a second argument to have the index start at 1. Then, construct your key using the first three elements of your row, and the new "index" of the item. Then, simply assign that value to that key in the dictionary. No need for multidicts.
csv_capacityatest = [[1, 1, 3, 1, 10, 5, 10],
[1, 2, 3, 7, 5, 3, 8 ],
[1, 4, 5, 9, 7, 2, 8 ],
[2, 1, 2, 0, 0, 0, 0 ],
[2, 3, 5, 6, 4, 3, 2 ],
[2, 5, 6, 7, 10, 4, 4 ],]
mydict_capacityatest = {}
for row in csv_capacityatest:
key_start = row[0:3]
for index, item in enumerate(row[3:], 1):
key = tuple(key_start [index])
mydict_capacityatest[key] = item
Which gives this dict:
{(1, 1, 3, 1): 1,
(1, 1, 3, 2): 10,
(1, 1, 3, 3): 5,
(1, 1, 3, 4): 10,
(1, 2, 3, 1): 7,
(1, 2, 3, 2): 5,
(1, 2, 3, 3): 3,
(1, 2, 3, 4): 8,
(1, 4, 5, 1): 9,
(1, 4, 5, 2): 7,
...
}