I am missing something small here and could use a pointer. I am trying to generate data to save time for my work with CRUD work in a database via pymonogo and other pythonic database libraries. Below is the code that I am having trouble with. I would like to create a function which creates a dictionary of length n but I cannot figure out how to append the dictionary appropriately. As you can see, it only enters in the last item of the list generated. Any input would be great!
import names
import random
import numpy as np
age_choices = np.arange(18, 90)
gender_choices = ['male', 'female']
salary_choices = np.arange(10000, 200000)
def create_data(n=20):
age_choices = np.arange(18, 90)
gender_choices = ['male', 'female']
salary_choices = np.arange(10000, 200000)
person_values = []
data_dict = {}
unique_id = 0
while unique_id < n:
age = random.choice(age_choices)
gender = random.choice(gender_choices)
salary = random.choice(salary_choices)
person_keys = ['id', 'name', 'gender', 'age', 'salary']
person_values = [unique_id, names.get_full_name(gender), gender, age, salary]
for k, v in zip(person_keys, person_values):
data_dict[k] = v
unique_id += 1
return person_values, data_dict
data_list, data_dict = create_data(5)
print(data_list)
print()
print(data_dict)
current outputs:
[4, 'Anthony Shultz', 'male', 29, 188503] # This is the last item of the list generated in the while loop
{'id': 4, 'name': 'Anthony Shultz', 'gender': 'male', 'age': 29, 'salary': 188503} # This is the "whole" dictionary generated but should have length 5 since n=5
The desired out put should be a dictionary of length n not just one.
You should introduce another variable in your function which would be a list or tuple and append each data_dict to it, every time you create one. You should also create a unique data_dict in your while loop, on every iteration. For example (check the lines with comments):
import names
import random
import numpy as np
age_choices = np.arange(18, 90)
gender_choices = ['male', 'female']
salary_choices = np.arange(10000, 200000)
def create_data(n=20):
age_choices = np.arange(18, 90)
gender_choices = ['male', 'female']
salary_choices = np.arange(10000, 200000)
person_values = []
all_data = [] # Make a list which will store all our dictionaries
unique_id = 0
while unique_id < n:
data_dict = {} # Create a dictionary with current values
age = random.choice(age_choices)
gender = random.choice(gender_choices)
salary = random.choice(salary_choices)
person_keys = ['id', 'name', 'gender', 'age', 'salary']
person_values = [unique_id, names.get_full_name(gender), gender, age,
salary]
for k, v in zip(person_keys, person_values):
data_dict[k] = v
all_data.append(data_dict) # Add newly created `data_dict` dictionary to our list
unique_id += 1
return person_values, data_dict, all_data # Return as desired
data_list, data_dict, all_data = create_data(5) # Just as an example
print(data_list)
print()
print(data_dict)
print()
print(all_data) # Print the output
This will result in list of dictionaries, which I assume you want as an output, e.g.:
[{'id': 0, 'name': 'David Medina', 'gender': 'male', 'age': 87, 'salary': 67957}, {'id': 1, 'name': 'Valentina Reese', 'gender': 'female', 'age': 68, 'salary': 132938}, {'id': 2, 'name': 'Laura Franklin', 'gender': 'female', 'age': 84, 'salary': 93839}, {'id': 3, 'name': 'Melita Pierce', 'gender': 'female', 'age': 21, 'salary': 141055}, {'id': 4, 'name': 'Brenda Clay', 'gender': 'female', 'age': 36, 'salary': 94385}]
Related
i have the below dataframe i want to filter the dataframe and return result based on the user selection from a multiselectbox , and grouped by name
the selectbox is the unique value of name field
import streamlit as st
import pandas as pd
data = {
'ID': [1, 2, 3, 4],
'name': ['peter', 'john', 'james', 'james'],
'nickname': ['pet', 'jon','james', 'jem'],
'mother_name': ['maria', 'linda', 'ana', 'beth'],
'bd': ['2000-05-15', '2006-09-12', '2004-10-25',]
}
with st.sidebar.form(key='search_form',clear_on_submit= False):
choices =df["name"].unique().tolist()
regular_search_term = st.multiselect(" ",choices)
if st.form_submit_button("search"):
df_result_search=df[df["name"].isin(regular_search_term)]
df_group = df_result_search.groupby('name')
st.write(df_group)
if i select james it return the 2 records while i need to return
1 record that includes the 2 data related to james
how can i return this result.
There is a missing value for the key bd in your data dictionnary.
You can use this :
import streamlit as st
import pandas as pd
data = {
'ID': [1, 2, 3, 4],
'name': ['peter', 'john', 'james', 'james'],
'nickname': ['pet', 'jon', 'james', 'jem'],
'mother_name': ['maria', 'linda', 'ana', 'beth'],
'bd': ['2000-05-15', '2006-09-12', '2004-10-25', '2004-10-26']
}
df = pd.DataFrame(data)
with st.sidebar.form(key='search_form', clear_on_submit=False):
choices = df["name"].unique().tolist()
regular_search_term = st.multiselect(" ", choices)
if st.form_submit_button("search"):
st.text('Filter on name')
st.write(df[df["name"].isin(regular_search_term)])
st.text('Filter on nickname')
st.write(df[df["nickname"].isin(regular_search_term)])
df_gr = df[['ID', 'nickname', 'mother_name', 'bd']
].astype(str).groupby(df['name']).agg('|'.join).reset_index()
st.text('Filter on name with grouped columns')
st.write(df_gr[df_gr["name"].isin(regular_search_term)])
>>> Output (in browser):
I let you choose whatever type of filter/display you want between the three.
there are list :
data = ['man', 'man1', 'man2']
key = ['name', 'id', 'sal']
man_res = ['Alexandra', 'RST01', '$34,000']
man1_res = ['Santio', 'RST009', '$45,000']
man2_res = ['Rumbalski', 'RST50', '$78,000']
the expected output will be nested output:
Expected o/p:- {'man':{'name':'Alexandra', 'id':'RST01', 'sal':$34,000},
'man1':{'name':'Santio', 'id':'RST009', 'sal':$45,000},
'man2':{'name':'Rumbalski', 'id':'RST50', 'sal':$78,000}}
Easy way would be using pandas dataframe
import pandas as pd
df = pd.DataFrame([man_res, man1_res, man2_res], index=data, columns=key)
print(df)
df.to_dict(orient='index')
name id sal
man Alexandra RST01 $34,000
man1 Santio RST009 $45,000
man2 Rumbalski RST50 $78,000
{'man': {'name': 'Alexandra', 'id': 'RST01', 'sal': '$34,000'},
'man1': {'name': 'Santio', 'id': 'RST009', 'sal': '$45,000'},
'man2': {'name': 'Rumbalski', 'id': 'RST50', 'sal': '$78,000'}}
Or you could manually merge them using dict + zip
d = dict(zip(
data,
(dict(zip(key, res)) for res in (man_res, man1_res, man2_res))
))
d
{'man': {'name': 'Alexandra', 'id': 'RST01', 'sal': '$34,000'},
'man1': {'name': 'Santio', 'id': 'RST009', 'sal': '$45,000'},
'man2': {'name': 'Rumbalski', 'id': 'RST50', 'sal': '$78,000'}}
#save it in 2D array
all_man_res = []
all_man_res.append(man_res)
all_man_res.append(man1_res)
all_man_res.append(man2_res)
print(all_man_res)
#Add it into a dict output
output = {}
for i in range(len(l)):
person = l[i]
details = {}
for j in range(len(key)):
value = key[j]
details[value] = all_man_res[i][j]
output[person] = details
output
The pandas dataframe answer provided by NoThInG makes the most intuitive sense. If you are looking to use only the built in python tools, you can do
info_list = [dict(zip(key,man) for man in (man_res, man1_res, man2_res)]
output = dict(zip(data,info_list))
How can I convert a Python-like dictionary into a flutter list?
here's my python dict fetched from a dataframe:
{0: {'id': '3422',
'Name': 'John',
}
1: {'id': '3322',
'Name': 'Mark',
}}
I want to convert it in this way:
final allUsers = <User>[
User(id: '3422', name:'John'),
User(id: '3322', name: 'Mark')]
dic = {0: {'id': '3422',
'Name': 'John',},
1: {'id': '3322',
'Name': 'Mark',
}}
flutter_value = ""
f_count = 0
for i in dic:
f_count+=1
count = 0
for j in dic[i]:
count+=1
if count == 1:
flutter_value+='User('+j+":'"+dic[i][j]+"'"
else:
flutter_value+=","+j+":'"+dic[i][j]+"')"
if f_count!=len(dic):
flutter_value+=","
flutter_value = ("final allUsers = <User>["+flutter_value+"]")
print(flutter_value)
Not sure how generic it is, but it can help you in small run I guess.
Output:
final allUsers = <User>[User(id: '3422', Name: 'John'),User(id: '3322', Name: 'Mark')]
This is my file: test.txt
Amy|Female|Desc1|12
John|Male|Desc2|10
Mike|Male|Desc3|18
I tried to create nested dictionary and it's not sucessful.
This is the output:
{'Amy': '12', 'John': '10', 'Mike': '18'}
This is my code:
import csv
with open('test.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
d = {}
for row in tsvfile:
d[row[0]] = row[0] #this should be name
d[row[0]] = row[1] #this should be gender
d[row[0]] = row[3] #this should be desc
d[row[0]] = row[3] #this should be age
print(d)
My desired output as below but was not successful.
d={1{'Name':'Amy', 'Gender':'Female', 'Desc': 'Desc1', 'Age': '12'}
2{'Name':'John', 'Gender':'Male', 'Desc': 'Desc2', 'Age': '10'}
3{'Name':'Mike', 'Gender':'Male', 'Desc': 'Desc3', 'Age': '18'}}
and below (with name and age only
d1={1{'Name':'Amy','Age': '12'}
2{'Name':'John', 'Age': '10'}
3{'Name':'Mike', 'Age': '18'}}
Here's how to do it without csv import, given the data format is constant:
fixed = {}
i = 1
with open("test.txt", 'r') as f:
for line in f:
listDetails = line.strip().split('|')
fixed[i] = {"Name": listDetails[0]}
fixed[i].update({"Sex": listDetails[1]})
fixed[i].update({"Description": listDetails[2]})
fixed[i].update({"Age": listDetails[3]})
i+=1
print(fixed)
This should turn
Amy|Female|Desc1|12
John|Male|Desc2|10
Mike|Male|Desc3|18
To
{1: {'Name': 'Amy', 'Sex': 'Female', 'Description': 'Desc1', 'Age': '12'}, 2: {'Name': 'John', 'Sex': 'Male', 'Description': 'Desc2', 'Age': '10'}, 3: {'Name': 'Mike', 'Sex': 'Male', 'Description': 'Desc3', 'Age': '18'}}
Edit: Just as Nakor said though, it doesn't really make sense to make a dict of dicts here, just posted this if you really need to make it a dict.
1) Nested Dictionary, I have made some changes in the same code, it may help you.
import csv
with open('hello.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
final_dict = {}
counter = 1
for row in tsvfile:
d = {}
d['Name'] = row[0] #this should be name
d['Gender'] = row[1] #this should be gender
d['Desc'] = row[2] #this should be desc
d['Age'] = row[3] #this should be age
final_dict[counter] = d
counter+=1
print(final_dict)
Your desired output looks more like a list of dictionaries.
In this case, I would just modify your code like this:
import csv
with open('test.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
d = []
for row in tsvfile:
entry = {
'Name': row[0],
'Gender': row[1],
'Desc': row[2],
}
d.append(entry)
print(d)
Output:
[{'Name': 'Amy', 'Gender': 'Female', 'Desc': 'Desc1'},
{'Name': 'John', 'Gender': 'Male', 'Desc': 'Desc2'},
{'Name': 'Mike', 'Gender': 'Male', 'Desc': 'Desc3'}]
You can even write the loop in a more compact way like this:
keys = ["Name","Gender","Desc"]
for row in tsvfile:
entry = { key: value for (key,value) in zip(keys,row) }
d.append(entry)
EDIT: If you want a dictionary with the line number as keys, you can do:
import csv
with open('test.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
d = {}
keys = ["Name","Gender","Desc"]
for i,row in enumerate(tsvfile):
entry = {
'Name': row[0],
'Gender': row[1],
'Desc': row[2],
}
d[i+1] = entry
print(d)
I am trying to create the table_data dictionary from Pandas dataframe like below:
import pandas as pd
d = {
'Name': ['John', 'Tom', 'Jack', 'Jill'],
'Age': [42, 53, 18, 22],
'City': ['London', 'New York', 'Bangkok', 'Warsaw']
}
df = pd.DataFrame(d)
table_data = dict(
headers = [[header] for header in list(df)],
columns = [df[header].tolist() for header in list(df)],
)
print(table_data)
Is there any way to avoid iterating over list(df) twice and turn those two list comprehensions into one?
Or does it defeat the purpose of list comprehension and I should use plain old for loop instead, like so?:
import pandas as pd
d = {
'Name': ['John', 'Tom', 'Jack', 'Jill'],
'Age': [42, 53, 18, 22],
'City': ['London', 'New York', 'Bangkok', 'Warsaw']
}
df = pd.DataFrame(d)
headers = []
columns = []
table_data = {
'headers': headers,
'columns': columns,
}
for header in list(df):
table_data['headers'].append([header])
table_data['columns'].append(df[header].tolist())
print(table_data)
Something like this:
header = [list(df.columns.values)]
values = df.values.T
table_data = dict(headers=header, columns=values)
Yes, it is possible by creating tuples first, then zip and convert tuples to lists:
L = [([header],df[header].tolist()) for header in list(df)]
h, c = zip(*L)
table_data = dict(
headers = list(h),
columns = list(c),
)
Non loop solution:
table_data = dict(
headers = df.columns.to_frame().values.tolist(),
columns = df.T.values.tolist(),
)
print(table_data)