How to read a 2d Dictionary from a csv file? - python

I have a CSV file and want to read the file to make a 2d dictionary.
I have tried creating a new dictionary:
f = csv.reader(open('test.csv', 'r'))
for row in f:
k, v, p = row
markovTransition[k] = {v: p}
The code above gives the output I want except It overwrites the key when the keys for the first dictionary are the same.
The CSV file is in the format of:
A,A1,3
A,A2,4
B,B1,6
C,C3,7
C,C2,3
C,C5,1
The desired dictionary is:
{A: {A1: 3, A2: 4}, B: {B1: 6}, C: {C3: 7, C2: 3, C5: 1}
The current dictionary is:
{A: {A2: 4}, B: {B1: 6}, C{C5: 1}}
How do I create a 2d dictionary from a CSV file? Thanks.

This is a nice use case for a defaultdict:
markovTransition=collections.defaultdict(dict)
f = csv.reader(open('test.csv', 'r'))
for row in f:
k, v, p = row
markovTransition[k][v] = p

try this:
markovTransition = {}
f = csv.reader(open('test.csv', 'r'))
for row in f:
k, v, p = row
if k in markovTransition.keys(): # Check if already exists and then push it.
markovTransition[k].update({v: p})
else:
markovTransition[k] = {v: p}

Related

I want to convert dictionary with tuples as keys to specific format and then store it in a file

I've a dictionary dic = {(1,2,3): 3, (2,3,4): 2, (3,4,8): 5}
I want it to be saved it in the text file output.txt with the specified format
1 2 3 (3)
2 3 4 (2)
3 4 8 (5)
modify the following code for this task
dic = {(1,2,3): 3, (2,3,4): 2, (3,4,8): 5}
with open('output.txt', 'w') as file:
file.write(str(dic))
Iterate the dictionary and write content to text file.
Ex:
dic = {(1,2,3): 3, (2,3,4): 2, (3,4,8): 5}
with open('output.txt', 'w') as file:
for k, v in dic.items(): #Iterate dic
file.write("{} ({}) \n".format(" ".join(map(str, k)), v)) #write to file.
dic = {(1,2,3): 3, (2,3,4): 2, (3,4,8): 5}
with open('output.txt', 'w') as file:
for k, v in dic.items(): #Iterate dic
file.write("{} ({}) \n".format(k, v)) #write to file.
Here we just have to pass the key and value to the format function. I dont think any other operations has to be done on this.
str.format() is one of the string formatting methods in Python3, which allows multiple substitutions and value formatting. This method allows to concatenate elements within a string through positional formatting.

How to combine a dictionary formatted excel file with dictionary in Python

If I have an excel file that has no row/column labels that looks like this:
and I have a dictionary that looks like this:
dict = {a:1, b:2, c:3}
How can I combine them into a dictionary that combines the values and that looks like this:
dict_result = {a:2, b:3, c:4}
Solution 1
If your excel file is in .xlsx format, you can use openpyxl:
import openpyxl
letter_map = {'a':1, 'b':2, 'c':3}
# open workbook
workbook = openpyxl.load_workbook('book1.xlsx')
# get worksheet by index
worksheet = workbook.worksheets[0]
result = {}
# loop over column pairs
for k, v in zip(worksheet['A'], worksheet['B']):
# assign new values to keys
result[k.internal_value] = v.internal_value + letter_map[k.internal_value]
print(result)
Output
{'a': 2, 'b': 3, 'c': 4}
Solution 2
If you have your excel file in .xls format, you can use xlrd:
import xlrd
letter_map = {'a':1, 'b':2, 'c':3}
# open work book
workbook = xlrd.open_workbook('book1.xls', on_demand=True)
# get sheet by index
worksheet = workbook.sheet_by_index(0)
result = {}
# loop over row indices
for row in range(worksheet.nrows):
# assign new values to keys
k, v = worksheet.cell(row, 0).value, worksheet.cell(row, 1).value
result[k] = int(v) + letter_map[k]
print(result)
Output
{'a': 2, 'b': 3, 'c': 4}
This solution works for csv file having columns A and B
import pandas as pd
actual_dict = {'a': 1, 'b': 1, 'c': 1}
cs = pd.read_csv(r'.\dict.csv')
keys = cs.A.tolist()
vals = cs.B.tolist()
csv_dict = {k:v for k,v in zip(keys,vals)}
for k in actual_dict.keys():
actual_dict[k] += csv_dict[k] #updating the actual dict

Replace values in Python dict

I have 2 files, The first only has 2 columns
A 2
B 5
C 6
And the second has the letters as a first column.
A cat
B dog
C house
I want to replace the letters in the second file with the numbers that correspond to them in the first file so I would get.
2 cat
5 dog
6 house
I created a dict from the first and read the second. I tried a few things but none worked. I can't seem to replace the values.
import csv
with open('filea.txt','rU') as f:
reader = csv.reader(f, delimiter="\t")
for i in reader:
print i[0] #reads only first column
a_data = (i[0])
dictList = []
with open('file2.txt', 'r') as d:
for line in d:
elements = line.rstrip().split("\t")[0:]
dictList.append(dict(zip(elements[::1], elements[0::1])))
for key, value in dictList.items():
if value == "A":
dictList[key] = "cat"
The issue appears to be on your last lines:
for key, value in dictList.items():
if value == "A":
dictList[key] = "cat"
This should be:
for key, value in dictList.items():
if key in a_data:
dictList[a_data[key]] = dictList[key]
del dictList[key]
d1 = {'A': 2, 'B': 5, 'C': 6}
d2 = {'A': 'cat', 'B': 'dog', 'C': 'house', 'D': 'car'}
for key, value in d2.items():
if key in d1:
d2[d1[key]] = d2[key]
del d2[key]
>>> d2
{2: 'cat', 5: 'dog', 6: 'house', 'D': 'car'}
Notice that this method allows for items in the second dictionary which don't have a key from the first dictionary.
Wrapped up in a conditional dictionary comprehension format:
>>> {d1[k] if k in d1 else k: d2[k] for k in d2}
{2: 'cat', 5: 'dog', 6: 'house', 'D': 'car'}
I believe this code will get you your desired result:
with open('filea.txt', 'rU') as f:
reader = csv.reader(f, delimiter="\t")
d1 = {}
for line in reader:
if line[1] != "":
d1[line[0]] = int(line[1])
with open('fileb.txt', 'rU') as f:
reader = csv.reader(f, delimiter="\t")
reader.next() # Skip header row.
d2 = {}
for line in reader:
d2[line[0]] = [float(i) for i in line[1:]]
d3 = {d1[k] if k in d1 else k: d2[k] for k in d2}
You could use dictionary comprehension:
d1 = {'A':2,'B':5,'C':6}
d2 = {'A':'cat','B':'dog','C':'house'}
In [23]: {d1[k]:d2[k] for k in d1.keys()}
Out[23]: {2: 'cat', 5: 'dog', 6: 'house'}
If the two dictionaries are called a and b, you can construct a new dictionary this way:
composed_dict = {a[k]:b[k] for k in a}
This will take all the keys in a, and read the corresponding values from a and b to construct a new dictionary.
Regarding your code:
The variable a_data has no purpose. You read the first file, pront the first column, and do nothing else with the data in it
zip(elements[::1], elements[0::1]) will just construct pairs like [1,2,3] -> [(1,1),(2,2),(3,3)], I think that's not what you want
After all you have a list of dictionaries, and at the last line you just put strings in that list. I think that is not intentional.
import re
d1 = dict()
with open('filea.txt', 'r') as fl:
for f in fl:
key, val = re.findall('\w+', f)
d1[key] = val
d2 = dict()
with open('file2.txt', 'r') as fl:
for f in fl:
key, val = re.findall('\w+', f)
d2[key] = val
with open('file3.txt', 'wb') as f:
for k, v in d1.items():
f.write("{a}\t{b}\n".format(a=v, b=d2[k]))

Update dictionary while parsing CSV file

I have csv file like this:
item,#RGB
item1,#ffcc00
item1,#ffcc00
item1,#ff00cc
item2,#00ffcc
item2,#ffcc00
item2,#ffcc00
item2,#ffcc00
....
and I want to make dictionary d, with item name as key and RGB value and count as tuples in list as dictionary value, like:
d[item] = [ (#RGB, count) ]
so for "item1" as in example, I would like to get:
d['item1'] = [ ('#ffcc00', 2), ('#ff00cc', 1) ]
I imagine some Pythonic iterator can do this in one line, but I can't understand how at this moment. So far I've made this:
d={}
with open('data.csv', 'rb') as f:
reader = csv.reader(f)
try:
for row in reader:
try:
if d[(row[0], row[1])]:
i +=1
except KeyError:
i = 1
d[(row[0], row[1])] = i
except csv.Error, e:
sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))
which gives me:
d[(item, #RGB)] = count
Any better way? Or am I doing this wrongly from start?
how about:
a = {}
for row in reader:
a.setdefault(row[0], {}).setdefault(row[1], 0)
a[row[0]][row[1]] += 1
This creates a dictionary like
{'item2': {'#00ffcc': 1, '#ffcc00': 3},
'item1': {'#ffcc00': 2, '#ff00cc': 1}}
I find it more convenient than your structure, but you can convert it to tuples if needed:
b = dict((k, v.items()) for k, v in a.items())
import csv
from collections import defaultdict, Counter
from itertools import islice
with open('infile.txt') as f:
d=defaultdict(Counter)
for k,v in islice(csv.reader(f),1,None):
d[k].update((v,))
print d
prints
defaultdict(<class 'collections.Counter'>, {'item2': Counter({'#ffcc00': 3, '#00ffcc': 1}), 'item1': Counter({'#ffcc00': 2, '#ff00cc': 1})})

make dictionary from csv file columns

i am new to the concept of dictionaries in python.
I have a csv file with multiple columns and i want to create a dictionary such that keys are taken from 1st column and values from the second and a key:value pair is made for all rows of those two columns.
The code is as follows:
if __name__=="__main__":
reader = csv.reader(open("file.csv", "rb"))
for rows in reader:
k = rows[0]
v = rows[1]
mydict = {k:v}
print (mydict)
problem: The output returned is only for "last" or "bottom most" row of the first two columns i.e. {'12654':'18790'}. i want the dictionary to contain all 100 rows of the first two columns in this format. How to do that? can i run some loop on the row numbers for the first two columns to do that...i dont know how.
if __name__=="__main__":
mydict = {}
reader = csv.reader(open("file.csv", "rb"))
for rows in reader:
k = rows[0]
v = rows[1]
mydict[k] = v
print mydict
Here:
mydict = {k:v}
You were making new dictionary in every iteration, and the previous data has been lost.
Update:
You can make something like this:
mydict = {}
L = [(1, 2), (2, 4), (1, 3), (3, 2), (3, 4)]
for el in L:
k, v = el
if not k in mydict:
mydict[k] = [v]
else:
mydict[k].append(v)
print mydict
>>>
{1: [2, 3], 2: [4], 3: [2, 4]}
This way, each value of the same key will be stored
Your code will be:
if __name__=="__main__":
mydict = {}
reader = csv.reader(open("file.csv", "rb"))
for i, rows in enumerate(reader):
if i == 0: continue
k = rows[0]
v = rows[1]
if not k in mydict:
mydict[k] = [v]
else:
mydict[k].append(v)
print mydict
Update2: You mean?
for k, v in mydict.items():
print "%s: %s" % (k, v)
>>>
1: [2, 3]
2: [4]
3: [2, 4]
Update3:
This should work:
if __name__=="__main__":
mydict = {}
reader = csv.reader(open("file.csv", "rb"))
for i, rows in enumerate(reader):
if i == 0: continue
k = rows[0]
v = rows[1]
if not k in mydict:
mydict[k] = [v]
else:
mydict[k].append(v)
print mydict
You are creating a new dict and overwriting the old one each iteration. #develerx's answer fixes this problem. I just wanted to point an easier way, using dict comprehensions:
Assuming the csv file contains two columns.
if __name__=="__main__":
reader = csv.reader(open("file.csv", "rb"))
my_dict = {k: v for k, v in reader}
print mydict
If you are using older version(older than 2.7 I think), you can't use dict comprehensions, just use the dict function then:
my_dict = dict((k, v) for k, v in reader)
Edit: And I just thought that; my_dict = dict(reader) could also work.

Categories

Resources