Python prettytable custom columns - python

I'm trying to create a prettytable with 4 columns. The information I'm trying to insert per row are located in different python dictionary. I would assume the code below will work but i'm receiving the error below
Exception: Row has incorrect number of values, (actual) 2!=4 (expected)
My code is:
t = PrettyTable(['key', 'Start', 'End', 'Retention'])
for key, val in total.items():
t.add_row([key, val])
for key, val in dic.items():
t.add_row([key, val])
print(t)

If you want to use values from both the total and dic dictionaries, You can use zip to iterate over them pairwise:
table = PrettyTable(['key', 'Start', 'End', 'Retention'])
for col_1_2, col_3_4 in zip(total.items(), dic.items()):
table.add_row([*col_1_2, *col_3_4])

your table is expecting 4 values for each row whereas you are entering only two values, that's the reason you are getting the error, so try this
for (k,v), (k2,v2) in zip(total.items(), dic.items()):
t.add_row([k, v, k2, v2])

Related

dictionary not properly called out in python

I have a made a dictionary and tried to call out the value but I am getting value of the excel cell row number also along with the cell value. I only want the values of the respective cells. Here's what I am getting while I run the code. I have attached the images. And why does it show dtype: object. Am I missing something in the code? or something is wrongly written.
def Trainreadin(actfile, actsheetname):
frame = Input.xclReadIn(actfile, actsheetname)
dict = {'resistance':
[']resistance_name(word)_A(N)_B(N/(km/h))_C(N/(km/h)2)_windT(km/h)_windB(km/h)', 'table']
outputdict = {key: framehandle.value_readin(value) for (key, value) in dict.items()}
outputdict["resistance_A"] = outputdict["resistance"][1]
outputdict["resistance_B"] = outputdict["resistance"][2] * 3.6
print(outputdict["resistance_A"])
return outputdict

add multiple values to one key, but defaultdict only allows 2

In the CSV I'm reading from, there are multiple rows for each ID:
ID,timestamp,name,text
444,2022-03-01T11:05:00.000Z,Amrita Patel,Hello
444,2022-03-01T11:06:00.000Z,Amrita Patel,Nice to meet you
555,2022-03-01T12:05:00.000Z,Zach Do,Good afternoon
555,2022-03-01T11:06:00.000Z,Zach Do,I like oranges
555,2022-03-01T11:07:00.000Z,Zach Do,definitely
I need to extract each such that I will have one file per ID, with the timestamp, name, and text in that file. For example, for ID 444, it will have 2 timestamps and 2 different texts in it, along with the name.
I'm able to get the text designated to the proper ID, using this code:
from collections import defaultdict
d = {}
l = []
list_of_lists = []
for k in csv_file:
l.append([k['ID'],k['text']])
list_of_lists.append(l)
for key, val in list_of_lists[0]:
d.setdefault(key, []).append(val)
The problem is that this isn't enough, I need to add in the other values to the one ID key. If I try:
l.append([k['ID'],[k['text'],k['name']]])
I get
ValueError: too many values to unpack
Just use a list for value instead,
{key: [value1, value2], ...}

Trying to Access keys in Dict from their values

I'm importing a CSV to a dictionary, where there are a number of houses labelled (I.E. 1A, 1B,...)
Rows are labelled containing some item such as 'coffee' and etc. In the table is data indicating how much of each item each house hold needs.
Excel screenshot
What I am trying to do it check the values of the key value pairs in the dictionary for anything that isn't blank (containing either 1 or 2), and then take the key value pair and the 'PRODUCT NUMBER' (from the csv) and append those into a new list.
I want to create a shopping list that will contain what item I need, with what quantity, to which household.
the column containing 'week' is not important for this
I import the CSV into python as a dictionary like this:
import csv
import pprint
from typing import List, Dict
input_file_1 = csv.DictReader(open("DATA CWK SHOPPING DATA WEEK 1 FILE B.xlsb.csv"))
table: List[Dict[str, int]] = [] #list
for row in input_file_1:
string_row: Dict[str, int] = {} #dictionary
for column in row:
string_row[column] = row[column]
table.append(string_row)
I found on 'geeksforgeeks' how to access the pair by its value. however when I try this in my dictionary, it only seems to be able to search for the last row.
# creating a new dictionary
my_dict ={"java":100, "python":112, "c":11}
# list out keys and values separately
key_list = list(my_dict.keys())
val_list = list(my_dict.values())
# print key with val 100
position = val_list.index(100)
print(key_list[position])
I also tried to do a for in range loop, but that didn't seem to work either:
for row in table:
if row["PRODUCT NUMBER"] == '1' and row["Week"] == '1':
for i in range(8):
if string_row.values() != ' ':
print(row[i])
Please, if I am unclear anywhere, please let me know and I will clear it up!!
Here is a loop I made that should do what you want.
values = list(table.values())
keys = list(table.keys())
new_table = {}
index = -1
for i in range(values.count("")):
index = values.index("", index +1)
new_table[keys[index]] = values[index]
If you want to remove those values from the original dict you can just add in
d.pop(keys[index]) into the loop

Dataframe to dictionary, values came out scrambled

I have a dataframe that contains two columns that I would like to convert into a dictionary to use as a map.
I have tried multiple ways of converting, but my dictionary values always comes up in the wrong order.
My python version is 3 and Pandas version is 0.24.2.
This is what the first few rows of my dataframe looks like:
geozip.head()
Out[30]:
Geoid ZIP
0 100100 36276
1 100124 36310
2 100460 35005
3 100460 35062
4 100460 35214
I would like my dictionary to look like this:
{100100: 36276,
100124: 36310,
100460: 35005,
100460: 35062,
100460: 35214,...}
But instead my outputs came up with the wrong order for the values.
{100100: 98520,
100124: 36310,
100460: 57520,
100484: 35540,
100676: 19018,
100820: 57311,
100988: 15483,
101132: 36861,...}
I tried this first but the dictionary came out unordered:
geozipmap = geozip.set_index('Geoid')['ZIP'].to_dict()
Then I tried coverting the two columns into list first then convert to dictionary, but same problem occurred:
geoid = geozip.Geoid.tolist()
zipcode = geozip.ZIP.tolist()
geozipmap = dict(zip(geoid, zipcode))
I tried converting to OrderedDict and that didn't work either.
Then I've tried:
geozipmap = {k: v for k, v in zip(geoid, zipcode)}
I've also tried:
geozipmap = {}
for index, g in enumerate(geoid):
geozipmap[geoid[index]] = zipcode[index]
I've also tried the answers suggested:
panda dataframe to ordered dictionary
None of these work. Really not sure what is going on?
try this default_dict and if same key have multiple values you can provide those as list
from collections import defaultdict
df =pd.DataFrame(data={"Geoid":[100100,100124,100460,100460,100460],
"ZIP":[36276,36310,35005,35062,35214]})
data_dict = defaultdict(list)
for k,v in zip(df['Geoid'],df['ZIP']):
data_dict[k].append(v)
print(data_dict)
defaultdict(<class 'list'>, {100100: [36276], 100124: [36310], 100460: [35005, 35062, 35214]})
Will this work for you?
dfG = df['Geoid'].values
dfZ = df['ZIP'].values
for g , z in zip (dfG,dfZ):
print(str(g)+':'+str(z))
This gives the output as below (but the values are strings)
100100:36276
100124:36310
100460:35005
100460:35062
100460:35214

A multi level nested list

I am trying to implement a customized automata where the transition table looks like:
The table is dynamic i.e. the column heading, row name, and data at every cell can be determined at run time. The column name and row name are also necessary.
I tried this code
table = []
table.append(["A",[0,["B",2],["C1",2]],[1,["C1",1]]])
table.append(["B",[0,["C",1]],[1,["C2",1]]])
table.append(["C",[0,["C1",1]],[1,["C2",1]]])
but I am unable to access the individual item in the cell i.e. B or 2 from B:2 etc. Then I tried
row = ["A","B","C","C1","C2"]
col = [0,1]
table = []
table.append([[["B",2],["C1",2]],["C1",1]])
table.append([["C",1],["C2",1]])
table.append([["C1",1],["C2",1]])
print(table[0][0][0][0])
Now, I can access the individual item (B in the above case) but I am lost with the four subscript. Specially, when I do not know the depth of the list in advance. Need to get some help to do it in some easy way. Being a novice, I will appreciate some explanation to the pythonic code.
Update: This is Non-deterministic Finite Automata. I tried the automaton package but they are not solving my problem. Following the solution of Tadhg-Mcdonald-Jensen, it give the correct out put for the first row (A) in the table but an error message for second row (B). Here is the code
table = {}
table["A"] = {0: {"B":2, "C1":2}, 1: {"C1":1}}
table["B"] = {0: {"C":1}, 1: {"C2",1}}
table["C"] = {0: {"C1":1}, 1: {"C2",1}}
for key,value in table["A"][0].items(): \\ok treated as dictionary (1)
print(key, value, sep="\t")
for key,value in table["A"][1].items(): \\ok treated as dictionary (2)
print(key, value, sep="\t")
for key,value in table["B"][0].items(): \\ok treated as dictionary (3)
print(key, value, sep="\t")
for key,value in table["B"][1].items(): \\wrong: why treated as set? Although same as (2)
print(key, value, sep="\t") \\Error message: AttributeError: 'set' object has no attribute 'items'
The output is
B 2
C1 2
C1 1
C 1
Traceback (most recent call last):
File "C:/Users/Abrar/Google Drive/Tourism Project/Python Projects/nestedLists.py", line 17, in <module>
for key,value in table["B"][1].items():
AttributeError: 'set' object has no attribute 'items'
Pandas is great at doing tables but you could also move to dictionaries, either way, list is not the data structure you want.
table = {}
table["A"] = {0: {"B":2, "C1":2}, 1: {"C1":1}}
table["B"] = {0: {"C":1}, 1: {"C2":1}}
table["C"] = {0: {"C1":1}, 1: {"C2":1}}
Then table["A"][0] will give you the first element, each element will have one or more entries, if you wanted to iterate over the entries you can do for key,value in table["A"][0].items()
Or to iterate over the entire table you could use 3 nested for loops:
#do_stuff = print
for row, line in table.items():
#each row in the table, row will go through ("A", "B", "C")
for column, cell in line.items():
#each cell in the row, column will go through (0, 1)
for label, value in cell.items():
#each entry in cell, most only have one entry except table["A"][0]
do_stuff(row, column, label, value)
To be honest I don't understand what the table represents so I can't give you specific advice but I think this would at least be a clearer data structure.

Categories

Resources