Reputation: 621
1) I first map the key names to a dictionary called main_dict with an empty list (the actual problem has many keys hence the reason why I am doing this)
2) I then loop over a data matrix consisting of 3 columns
3) When I append a value to a column (the key) in the dictionary, the data is appended to wrong keys.
Where am I going wrong here?
Minimum working example: Edit: The data is being read from a file row by row and does not exist in lists as in this MWE. Edit2: Prefer a more pythonic solution than Pandas.
import numpy as np
key_names = ["A", "B", "C"]
main_dict = {}
val = []
main_dict = main_dict.fromkeys(key_names, val)
data = np.array([[2018, 1.1, 3.3], [2017, 2.1, 5.4], [2016, 3.1, 1.4]])
for i in data:
main_dict["A"].append(i[0])
main_dict["B"].append(i[1])
main_dict["C"].append(i[2])
print(main_dict["A"])
# Actual output: [2018.0, 1.1, 3.3, 2017.0, 2.1, 5.4, 2016.0, 3.1, 1.4]
# print(main_dict["A"])
# Expected output: [2018.0, 2017.0, 2016.0]
# print(main_dict["B"])
# Expected output: [1.1, 2.1, 3.1]
# print(main_dict["C"])
# Expected output: [3.3, 5.4, 1.4]
Upvotes: 1
Views: 165
Reputation: 427
The problem is in
main_dict = main_dict.fromkeys(key_names, val)
The same list val is referenced by all the keys since python passes reference.
Upvotes: 0
Reputation: 7887
Without using numpy (which is a heavy weight package for what you are doing) I would do this:
keys = ["A", "B", "C"]
main_dict = {key: [] for key in keys}
data = [[2018, 1.1, 3.3], [2017, 2.1, 5.4], [2016, 3.1, 1.4]]
# since you are reading from a file
for datum in data:
for index, key in enumerate(keys):
main_dict[key].append(datum[index])
print(main_dict) # {'A': [2018, 2017, 2016], 'B': [1.1, 2.1, 3.1], 'C': [3.3, 5.4, 1.4]}
Alternatively you can use the built-in defaultdict
which is a tad faster since you don't need to do the dictionary comprehension:
from collections import defaultdict
main_dict = defaultdict(list)
keys = ["A", "B", "C"]
data = [[2018, 1.1, 3.3], [2017, 2.1, 5.4], [2016, 3.1, 1.4]]
# since you are reading from a file
for datum in data:
for index, key in enumerate(keys):
main_dict[key].append(datum[index])
print(main_dict)
Lastly, if the keys really don't matter to you, you can be a little more dynamic by coming up with the keys dynamically starting from A
. Thus allowing lines to have more than three attributes:
from collections import defaultdict
main_dict = defaultdict(list)
data = [[2018, 1.1, 3.3], [2017, 2.1, 5.4], [2016, 3.1, 1.4]]
# since you are reading from a file
for datum in data:
for index, attr in enumerate(datum):
main_dict[chr(ord('A') + index)].append(attr)
print(main_dict) # {'A': [2018, 2017, 2016], 'B': [1.1, 2.1, 3.1], 'C': [3.3, 5.4, 1.4]}
Upvotes: 1