I have some student names of different types and scores of each type in a list.
Eg:
students_exam_names = [exam_name1, exam_name2, exam_name3]
students_exam_score = [exam_score1, exam_score2, exam_score3]
students_quiz_names = [quiz_name1, quiz_name2]
students_quiz_score = [quiz_score1, quiz_score2]
students_homework_names = [homework_name1, homework_name2, homework_name3, homework_name4]
students_homework_score = [homework_score1, homework_score2, homework_score3, homework_score4]
Similarly for all three as shown below.
I want to have the details in the form of nested dict as follows:
details = {'students_exam':{
'exam_name1':exam_score1,
'exam_name2':exam_score2,
'exam_name3':exam_score3
},
'students_quiz':{
'quiz_name1': quiz_score1,
'quiz_name2': quiz_score2
},
'students_homework':{
'homework_name1': homework_score1,
'homework_name2': homework_score2,
'homework_name3': homework_score3,
'homework_name4': homework_score4,
}
The length of each students type is different. I tried to get it in the form of list of dictionaries as below but couldn't go further.
students_exam = {}
for i in range(len(students_exam_names)):
students_exam[students_exam_names[i]] = students_exam_score[i]
Do not forget to use ' when you are defining your inputs:
students_exam_names = ['exam_name1', 'exam_name2', 'exam_name3']
students_exam_score = ['exam_score1', 'exam_score2', 'exam_score3']
students_quiz_names = ['quiz_name1', 'quiz_name2']
students_quiz_score = ['quiz_score1', 'quiz_score2']
students_homework_names = ['homework_name1', 'homework_name2', 'homework_name3', 'homework_name4']
students_homework_score = ['homework_score1', 'homework_score2', 'homework_score3', 'homework_score4']
Then, simply use the zip function:
details = {'students_exam': dict(zip(students_exam_names, students_exam_score)),
'students_quiz': dict(zip(students_quiz_names, students_quiz_score)),
'students_homework': dict(zip(students_homework_names, students_homework_score))}
The output is:
{'students_exam': {'exam_name1': 'exam_score1', 'exam_name2': 'exam_score2', 'exam_name3': 'exam_score3'}, 'students_quiz': {'quiz_name1': 'quiz_score1', 'quiz_name2': 'quiz_score2'}, 'students_homework': {'homework_name1': 'homework_score1', 'homework_name2': 'homework_score2', 'homework_name3': 'homework_score3', 'homework_name4': 'homework_score4'}}
So what if i assume your complete set of inputs are like
students_exam_names = ['name1', 'name2', 'name3']
students_exam_score = ['score1', 'score2', 'score3']
students_quiz_names = ['name1', 'name2']
students_quiz_score = ['score1', 'score2']
students_homework_names = ['name1', 'name2', 'name3', 'name4']
students_homework_score = ['score1', 'score2', 'score3', 'score4']
if so then the following code should do the job.
details={}
details['students_exam']={sexam: students_exam_score[students_exam_names.index(sexam)] for sexam in students_exam_names}
details['students_quiz']={squiz: students_quiz_score[students_quiz_names.index(squiz)] for squiz in students_quiz_names}
details['students_homework']={shome: students_homework_score[students_homework_names.index(shome)] for shome in students_homework_names}
It looks like you need some functions to do these updates:
def update_exam(details, names, scores):
results = {}
for name,score in zip(names,scores):
results[name]=score
details['students_exam'] = results
def update_quiz(details, names, scores):
results = {}
for name,score in zip(names,scores):
results[name]=score
details['students_quiz'] = results
def update_homework(details, names, scores):
results = {}
for name,score in zip(names,scores):
results[name]=score
details['students_homework'] = results
details = {}
update_exam(details, students_exam_names, students_exam_score)
update_quiz(details, students_quiz_names, students_quiz_score)
update_homework(details, students_homework_names, students_homework_score)
But since the above functions only really differ in the text name of the key, they can be collapsed further:
def update(details, key, names, scores):
results = {}
for name,score in zip(names,scores):
results[name]=score
details[key] = results
details = {}
update(details,'students_exam', students_exam_names, students_exam_score)
update(details,'students_quiz', students_quiz_names, students_quiz_score)
update(details,'students_homework', students_homework_names, students_homework_score)
And then the loop can become a dictionary comprehension:
def update(details, key, names, scores):
details[key] = {name:score for (name,score) in zip(names,scores)}
Related
need to save them into different data frames
query = '''select name
from my_table
where class = {}
and student_number > {}
and student_number <= {} +10
group by name'''
inputs = list(range(0, 100,10))
classes = [1,2,3,4]
the expected result is running these batches for each class individually. e.g df_class1, df_class2 df_class3, df_class4
query = '''
select name from my_table where class = {} and student_number >
{} and student_number <= {} +50 group by name'''
inputs = list(range(0, 100,10))
classes = [1,2,3,4]
not sure on this part ##for i in inputs: for c in classes: query.format(c, i, i)##
results = pd.DataFrame() for input, query in queries.items():
res = my_db.execute(query)
results = results.append(pd.DataFrame(res))
each results as sth like ;df_class1, df_class2 df_class3, df_class4
You can use formatted string to save the resultant dataframe for each iteration.
inputs = list(range(0, 100,10))
classes = [1,2,3,4]
for i in inputs:
for c in classes:
query.format(c, i, i)
res = my_db.execute(query)
df = pd.DataFrame(res)
df.to_csv(f'result_{i}_{c}.csv')
Im currently writing an menu where you can create, read, update, delete products from a deposit, so my proffesor told me to use .txt file as a "database" not really a database but only to store some information. My question is that i searched everywhere how to create a nested list from user input and insert it in the text file and all i have right now is that i can create a list for each product like : ['Product1', 'quantity', 'price'] ['Product2', 'quantity', 'price'], but i cant create a nested list like this: [['Product1', 'quantity', 'price'], ['Product2', 'quantity', 'price']] so i can print a product with all his details like qty and price.. here is my code:
def adaugaProdus():
nume = input("Introduceti numele produsului:")
cantitate = int(input("Introduceti cantitatea :"))
pret = int(input("Introduceti pretul:"))
produse = []
produse.append(nume)
produse.append(cantitate)
produse.append(pret)
depozit = open("depozit.txt", "a")
depozit.write(str(produse))
depozit.write("\n")
depozit.close()
I've added a little bit to your code to show you that you can "nest" the lists. I think you were definitely on the right track with your answer:
#!/usr/bin/env python3
def adaugaProdus():
products = [] # Initialize the list of prducts
for product in range(2): # We'll ask user for 2 products - you can choose a different way to terminate the loop as needed
nume = input("Introduceti numele produsului:")
cantitate = int(input("Introduceti cantitatea :"))
pret = int(input("Introduceti pretul:"))
produse = []
produse.append(nume)
produse.append(cantitate)
produse.append(pret)
products.append(produse) # Adding to the list of lists
depozit = open("depozit.txt", "a")
depozit.write(str(products))
depozit.write("\n")
depozit.close()
adaugaProdus()
And here's another version using PyYAML. YAML is a format that allows the program to write the data, but more importantly it allows the program to read the program easily, too. As an important added bonus, it's easy for us dumb humans to edit!
Here's the modified program:
#!/usr/bin/env python3
import yaml # you'll need to 'pip install PyYaml' first
def adaugaProdus():
products = [] # Initialize the list of prducts
for product in range(2): # We'll ask user for 2 products - you can choose a different way to terminate the loop as needed
nume = input("Introduceti numele produsului:")
cantitate = int(input("Introduceti cantitatea :"))
pret = int(input("Introduceti pretul:"))
produse = []
produse.append(nume)
produse.append(cantitate)
produse.append(pret)
products.append(produse) # Adding to the list of lists
with open("depozit.yaml", "w") as f:
yaml.dump( products, f )
adaugaProdus()
And here's the user session and depozit.yaml file:
Introduceti numele produsului:P1
Introduceti cantitatea :1
Introduceti pretul:1
Introduceti numele produsului:P2
Introduceti cantitatea :2
Introduceti pretul:2
$ cat depozit.yaml
- - P1
- 1
- 1
- - P2
- 2
- 2
And here's an example of a program that can read depozit.yaml:
import yaml
with open("depozit.yaml") as f:
products = yaml.safe_load( f )
print(products)
And the output:
[['P1', 1, 1], ['P2', 2, 2]]
you should use dictionary :
# Creating an empty dictionary
myDict = {}
# Adding list as value
myDict["key1"] = [1, 2]
# creating a list
list = ['Product1', 'quantity', 'price']
# Adding this list as sublist in myDict
myDict["key1"].append(list)
print(myDict)
I would change this to a list of dict items and then use the json standard module. It will make your life a lot easier. See the example below...
import json
def to_dict(nume, cantitate, pret):
return {
"nume": nume,
"cantitate": cantitate,
"pret": pret
}
def get_input():
nume = input("Introduceti numele produsului:")
cantitate = int(input("Introduceti cantitatea :"))
pret = int(input("Introduceti pretul:"))
return nume, cantitate, pret
produse_list = []
# one way
nume, cantitate, pret = get_input()
produse_list.append(to_dict(nume, cantitate, pret))
# other way
produse_list.append(to_dict(*get_input()))
print(produse_list)
with open("output.json", "w") as outfile:
json.dump(produse_list, outfile)
with open("output.json") as infile:
produse_list_2 = json.load(infile)
print(produse_list_2)
You can combine all inputs in a list and then append it to produse. This will create a nested list like [['Product1', 'quantity', 'price'], ['Product2', 'quantity', 'price']]:
def adaugaProdus():
nume = input("Introduceti numele produsului:")
cantitate = int(input("Introduceti cantitatea :"))
pret = int(input("Introduceti pretul:"))
produse = []
produse.append([nume, cantitate, pret]) # This is the modified line.
depozit = open("depozit.txt", "a")
depozit.write(str(produse))
depozit.write("\n")
depozit.close()
I am trying to edit this function so the values of the dictionary will not be printed in parentheses and will be iterable:
def traverse_appended(key):
reg_dict = {}
#keypath = r"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
for item in traverse_reg(key):
keypath_str = str(keypath+item)
reg_dict[item] = str(get_reg("Displayversion", keypath_str)), str(get_reg("DisplayName", keypath_str))
#reg_dict[item] = get_reg("DisplayName", keypath_str)
return reg_dict
the expected output is :
{'DXM_Runtime': 'None', 'None'}
The function output:
{'DXM_Runtime': ('None', 'None')}
#Consider traverse_appended returns following dict.
#I think, converting func_dict values which are tuple into string, will help you to get expected output.
func_dict = {"DXM_Runtime":('None','None'),
"TMP_KEY":('A','B')
}
derived_dict = {}
for k,v in func_dict.viewitems():
tmp_str = ",".join(v)
derived_dict[k] = tmp_str
print derived_dict
#Output
E:\tmp_python>python tmp.py
{'DXM_Runtime': 'None,None', 'TMP_KEY': 'A,B'}
#If this doesn't help you, then please post the code for get_reg and traverse_reg function also.
How to add different values in the same key of a dictionary? These different values are added
in a loop.
Below is what I desired entries in the dictionary data_dict
data_dict = {}
And during each iterations, output should looks like:
Iteration1 -> {'HUBER': {'100': 5.42}}
Iteration2 -> {'HUBER': {'100': 5.42, '10': 8.34}}
Iteration3 -> {'HUBER': {'100': 5.42, '10': 8.34, '20': 7.75}} etc
However, at the end of the iterations, data_dict is left with the last entry only:
{'HUBER': {'80': 5.50}}
Here's the code:
import glob
path = "./meanFilesRun2/*.txt"
all_files = glob.glob(path)
data_dict = {}
def func_(all_lines, method, points, data_dict):
if method == "HUBER":
mean_error = float(all_lines[-1]) # end of the file contains total_error
data_dict["HUBER"] = {points: mean_error}
return data_dict
elif method == "L1":
mean_error = float(all_lines[-1])
data_dict["L1"] = {points: mean_error}
return data_dict
for file_ in all_files:
lineMthds = file_.split("_")[1] # reading line methods like "HUBER/L1/L2..."
algoNum = file_.split("_")[-2] # reading diff. algos number used like "1/2.."
points = file_.split("_")[2] # diff. points used like "10/20/30..."
if algoNum == "1":
FI = open(file_, "r")
all_lines = FI.readlines()
data_dict = func_(all_lines, lineMthds, points, data_dict)
print data_dict
FI.close()
You can use dict.setdefault here. Currently the problem with your code is that in each call to func_ you're re-assigning data_dict["HUBER"] to a new dict.
Change:
data_dict["HUBER"] = {points: mean_error}
to:
data_dict.setdefault("HUBER", {})[points] = mean_error
You can use defaultdict from the collections module:
import collections
d = collections.defaultdict(dict)
d['HUBER']['100'] = 5.42
d['HUBER']['10'] = 3.45
I am trying to create a nested dictionary from a mysql query but I am getting a key error
result = {}
for i, q in enumerate(query):
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email
error
KeyError: 'data'
desired result
result = {
'data': {
0: {'firstName': ''...}
1: {'firstName': ''...}
2: {'firstName': ''...}
}
}
You wanted to create a nested dictionary
result = {} will create an assignment for a flat dictionary, whose items can have any values like "string", "int", "list" or "dict"
For this flat assignment
python knows what to do for result["first"]
If you want "first" also to be another dictionary you need to tell Python by an assingment
result['first'] = {}.
otherwise, Python raises "KeyError"
I think you are looking for this :)
>>> from collections import defaultdict
>>> mydict = lambda: defaultdict(mydict)
>>> result = mydict()
>>> result['Python']['rules']['the world'] = "Yes I Agree"
>>> result['Python']['rules']['the world']
'Yes I Agree'
result = {}
result['data'] = {}
for i, q in enumerate(query):
result['data']['i'] = {}
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email
Alternatively, you can use you own class which adds the extra dicts automatically
class AutoDict(dict):
def __missing__(self, k):
self[k] = AutoDict()
return self[k]
result = AutoDict()
for i, q in enumerate(query):
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email
result['data'] does exist. So you cannot add data to it.
Try this out at the start:
result = {'data': []};
You have to create the key data first:
result = {}
result['data'] = {}
for i, q in enumerate(query):
result['data'][i] = {}
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email