How to get the desired value of the dictionary? - python

First off, i'm new to python and trying to create a dynamic dictionary :
editdistances = { r.name : editdistance.eval(baseline.result, r.result)}
note that i'm running a for r in values: above r having 2 instances name and value.Now the thing is i want to append the value part(editdistance.eval(baseline.result, r.result) in a table
table.append(editdistances[x])
this is what i tried but pretty sure it's wrong because it's not referencing the value. How can i fix it and still know what's the name (r.name) of each value in the table.
Edit: Just noticed another issue in editdistances = { r.name : editdistance.eval(baseline.result, r.result)} basically let's say i have 3 students, student1,student 2 and student 3. And i want to input 3 grades for each one at a time using a loop, basically first iteration student1 :16..second iteration student1:16 student2 :12..third iteration student1:16 student2 :12 student3:9..4th iteration student1:16,7 student2 :12 student3:9 ...and so on, how can i do that and still be able to refer to each grade indivudually assuming each refers to a different course.

editdistances = { 'r.name' : "editdistance.eval(baseline.result, r.result)"}
table=[]
for r in editdistances:
table.append(editdistances[r])
print (table)
Output
['editdistance.eval(baseline.result, r.result)']

You can access the value for a given key in a dictionary this way (assuming r has a property values:
for value in r.values:
table.append(editdistances[value])
If values is a method of r then you also need to add brackets:
for value in r.values():
table.append(editdistances[value])

This seems more like you're asking how to use a dictionary.
"how can i do that and still be able to refer to each grade indivudually assuming each refers to a different course"
Create a dictionary with each student as a key in the first level.
Then each student is a dictionary, with a course-name for keys, and the grades attached as values:
students = {
'student1' : {'class1' : 'grade1', 'class2' : 'grade2', 'class3' : grade3'},
'student2' : {'class1' : 'grade1', 'class2' : 'grade2', 'class3' : grade3'},
'student3' : {'class1' : 'grade1', 'class2' : 'grade2', 'class3' : grade3'}
}
for student in students:
for class_name in student:
# print the student's name, class name, and their grade for that class.
print (student, class_name, students[student][class_name])
Given your current question, the question itself isn't written that clearly
And you have dependency code/data-structuring that you mention briefly but don't allow to be fully described.
Please provide that dependency code so we can see what you're talking about. For example, the sentence "I am doing this in a for loop" is way more characters than
just pasting the exact and original code.

Related

Python, most compact&efficeint way of checking if an item is any of the lists (which are inside dictionaries)?

I have a dictionary with lists (with strings inside) and I need I need to check if a string appears anywhere among those lists.
Here is an example
classes = {
"class_A" : ["Mike","Alice","Peter"],
"class_B" : ["Sam","Robert","Anna"],
"class_C" : ["Tom","Nick","Jack"]
}
students=["Alice","Frodo","Jack"]
for student in students:
if student *in any of the classes*:
print("Is here")
else:
print("Is not here")
For every student in the list I provided: if that student is in any of the classes, do A, if not do B.
Currently the output is Is here, Is not here, Is here
Here is my current code:
studentsInClasses=[]
for studentsInClass in classes.values()
studentsInClasses+=studentsInClass
students=["Alice","Frodo","Jack"]
for student in students:
if student in studentsInClasses:
print("Is here")
else:
print("Is not here")
But this is happening inside a complex structure of classes, functions and loops so it become a major performance issue as soon as I scale up the inputs.
Here is something that I do like, but is a bit annoying as I have to make sure that whatever function my code is in, has access to this one:
def check(student,classes):
for value in classes.values():
if student in value:
return True
return False
It is probably as good as it gets, but I would like to know if there is a simple one liner that does the job.
Requirements:
Does not create a copy of the lists
Does not rely on keys in any way
Preferably nice and simple
Isn't an over-engineered superefficient solution
I am new to stack overflow, if I am doing any major mistakes in my way of posting please do tell, I will try to improve my question writing.
Thanks
If a generator expression is acceptable with regards to your requirements, then:
def check(student, classes):
return any(student in value for value in classes.values())
And to get a boolean for each student, you could create this function:
def checkall(students, classes):
return [any(student in value for value in classes.values())
for student in students]
For your sample data, this would return [True, False, True].
If allowed, I guess you'd increase performance if you delete the entry within the class, whenever you had a match.
Use sorting beforehand
studentsInClasses=[]
for studentsInClass in classes.values()
studentsInClasses+=studentsInClass
studentsInClasses = sorted(studentsInClasses)
students=sorted(["Alice","Frodo","Jack"])
lastMatch=0
for i in range(len(students)):
student = students[i]
try:
lastMatch = studentsInClasses[lastMatch:].index(student)
print(f"{student} in class")
except ValueError as e:
pass
So if you want to just print is here or is not here here is an example:
classes = {
"class_A" : ["Mike","Alice","Peter"],
"class_B" : ["Sam","Robert","Anna"],
"class_C" : ["Tom","Nick","Jack"]
}
for line in str(classes).split(","):
if student in line:
print("Student in here")
else:
print("Student not here")
Since this is in a loop, you should create a set for all of the values:
from itertools import chain
values = set(chain(*classes.values()))
students=["Alice","Frodo","Jack"]
for student in students:
if student in values:
print("Is here")
else:
print("Is not here")
The reason is that a set lookup is a constant time lookup, and in a tight loop makes a big difference
How about making the list of students in each class a set?
Then the lookup time will be o(1) and you can loop over n classes.
The you can have:
class_to_students = {
"class_A" : {"Mike","Alice","Peter"},
"class_B" : {"Sam","Robert","Anna"},
"class_C" : {"Tom","Nick","Jack"}
}
students=["Alice","Frodo","Jack"]
for student in students:
for class_students in class_to_students.values():
if student in class_students:
print(f"{student} Is here")
break
else:
# loop was not broken out of
print(f"{student} Is not here")
-->
Alice Is here
Frodo Is not here
Jack Is here
If you exclude a solution like this, then you are stuck with your n*m solution where n is the number of classes and m is the number of students in each class.
Is this something you are looking for?
classes = {
"class_A": ["Mike","Alice","Peter"],
"class_B": ["Sam","Robert","Anna"],
"class_C": ["Tom","Nick","Jack"]
}
students = ["Alice", "Frodo", "Jack"]
res = [student in class_ for class_ in classes.values() for student in students ]
print(res)

Using variables of equal value as dictionary keys results in overwritten values (Python)

I have a Python dictionary as below:
Mail_Dict = {
MailList0 : CodeList0,
MailList1 : CodeList1,
MailList2 : CodeList2,
MailList3 : CodeList3,
MailList4 : CodeList4
}
The issue is when one of the MailLists have values that are the same as another MailList (ie: MailList0 = 'someone#email.com' and also MailList1 = 'someone#email.com'), the keys are treated as equal and CodeList0 gets overwritten by CodeList1, also making my dictionary shorter in the process.
Is there anyway to keep these separate? I would think that the same logic for below:
a=1
b=1
saving to separate memory addresses and being different from:
a=b=1
would apply here, but I guess that isn't the case =(
Thanks in advance.
If you want to create both the values of the same key in the dictionary, one solution would be to add the old value to a list and append the new value to the list.
Mail_Dict = {
MailList0 : CodeList0,
MailList2 : CodeList2,
MailList3 : CodeList3,
MailList4 : CodeList4
}
Now if you want to add MailList1 (which has the same value as MailList0) to the dictionary, check if MailList1 already is a list. if it is not a list make it into a list and then append the new value.
if(MailList1 in Mail_Dict):
if (isinstance(Mail_Dict[MailList1],list)==False):
Mail_Dict[MailList1] = [Mail_Dict[MailList1]
Mail_Dict[MailList1].append(codeList1)

am new to python, please share logic for below concept

Eg:
ECE_student_list = [['section-1', [["sai",'science'], ["rama",'maths']]],
['section-2', [["seetha",'science'], ["ravana",'maths']]]]
I have to print student name and subject by passing key as section name.
for Eg : if the key is 'section-1' first student then it should print "sai",'science'
second student ,then it should print "rama",'maths'
please share the logic in python.
Won't share the code directly. That you have to learn and experiment on your own. Although I can tell you what you can expect as your output.
You can create a dictionary in python and add section-1, section-2 as the keys and the list of students as value for each key.
Your dictionary structure will be something like this:
{
'section-1' : [
{'sai':'science'},
{'rama':'math'}
],
'section-2':[
{'sai':'science'},
{'rama':'math'}
]
}

Using append to get data from a nested list

Currently my code is like this:
.append("Last Name {}, First Name {} Stats: {}".format(result["L_Name"], result["F_Name"], result["Stats"]))
this code works but the output isn't exactly the ones I want the code to display.
the problem is that the Stats has another list
L_Name: Doe
F_Name: John
Contribution:
Month
Value
Returns
is there a way to just pick out only the Value from the Stats by just adding or changing something in my append?
specifically in this part?
, result["Stats"]))
If you are only after one value of Stats, you can get the value at a certain index. Assuming Value is at index 1 and Stats is a standard Python list:
, result["Stats"][1]))
Notice that you can access the items of the JSON structure in the format string itself. This is clearer than using positional arguments if the format string is very complicated. Additionally, you can pass the whole dictionary into format_map:
l.append("Last Name {L_Name}, First Name {F_Name} Stats: {Stats[Value]}"
.format_map(result))
(In Python 2, format_map doesn't exist, use format(**result) instead.
In the future please consider posting working code only so we can reproduce your issue. I am going to assume result['stats'] is a dictionary and the bulleted list are key:value pairs.
You can access the "Contribution" key of your result["Stats"] dictionary which results in list. You can then slice the second element of the list with [1].
_.append("Last Name {}, First Name {} Stats: {}".format(
result["L_Name"],
result["F_Name"],
result["Stats"]["Contribution"][1]))
This assumes result['stats'] looks like:
result['stats'] = {
'L_Name': 'Doe',
'F_Name': 'John',
'Contribution': [Month, Value, Returns]}
Thanks everyone I was able to get a hint from your answers
result["Stats"]["Contribution"][1]
worked well for me

How to query for distinct results in mongodb with python?

I have a mongo collection with multiple documents, suppose the following (assume Tom had two teachers for History in 2012 for whatever reason)
{
"name" : "Tom"
"year" : 2012
"class" : "History"
"Teacher" : "Forester"
}
{
"name" : "Tom"
"year" : 2011
"class" : "Math"
"Teacher" : "Sumpra"
}
{
"name" : "Tom",
"year" : 2012,
"class" : "History",
"Teacher" : "Reiser"
}
I want to be able to query for all the distinct classes "Tom" has ever had, even though Tom has had multiple "History" classes with multiple teachers, I just want the query to get the minimal number of documents such that Tom is in all of them, and "History" shows up one time, as opposed to having a query result that contains multiple documents with "History" repeated.
I took a look at:
http://mongoengine-odm.readthedocs.org/en/latest/guide/querying.html
and want to be able to try something like:
student_users = Students.objects(name = "Tom", class = "some way to say distinct?")
Though it does not appear to be documented. If this is not the syntactically correct way to do it, is this possible in mongoengine, or is there some way to accomplish with some other library like pymongo? Or do i have to query for all documents with Tom then do some post-processing to get to unique values? Syntax would be appreciated for any case.
First of all, it's only possible to get distinct values on some field (only one field) as explained in MongoDB documentation on Distinct.
Mongoengine's QuerySet class does support distinct() method to do the job.
So you might try something like this to get results:
Students.objects(name="Tom").distinct(field="class")
This query results in one BSON-document containing list of classes Tom attends.
Attention Note that returned value is a single document, so if it exceeds max document size (16 MB), you'll get error and in that case you have to switch to map/reduce approach to solve such kind of problems.
import pymongo
posts = pymongo.MongoClient('localhost', 27017)['db']['colection']
res = posts.find({ "geography": { "$regex": '/europe/', "$options": 'i'}}).distinct('geography')
print type(res)
res.sort()
for line in res:
print line
refer to http://docs.mongodb.org/manual/reference/method/db.collection.distinct/
distinct returns a list , will be printed on print type(res) , you can sort a list with res.sort() , after that it will print the values of the sorted list.
Also you can query posts before select distinct values .
student_users = Students.objects(name = "Tom").distinct('class')

Categories