Removing list object given field value python - python-2.7

Given
This is not simply removing elements from a list; its removing but by using field value
philani = Student(20, "Philani Sithole", "Male", [64,65])
sarah = Student(19, "Sarah Jones", "Female", [82,58])
fabian = Student(50, "Fabian Hamza", "Male", [50,52])
students = [philani, sarah, fabian]
How can I remove the object fabian from students list given the name "Fabian Hamza"
Desired results:
students = [philani, sarah]
It tried this
name = "Fabian Hamza"
for i in xrange(len(students)):
if hasattr(students[i], name):
students.pop(i)
But its not working

You can use a list comprehension to achieve that:
[s for s in students if s.name != 'Fabian Hamza']
If you want just the list of names, try:
[s.name for s in students if s.name != 'Fabian Hamza']

Related

Sml tuples length

I was interested in if there is a possible way to get length of tuple in sml?! See example
val tes = ((1,"test"),("test","some"))
Lenght(tes) = 2
I want it for a problem solve there is a problem which says to get students list which contains list for each student information but student information are different in two types some are like
(1,"test","nick")
and some are like
("name","nick")
So it wants to return the first element of each list in student lists see below:
((1,"test","nick"),("test2","nick2"),(2,"test3","nick3"))
Return > (1,"test2",2)
Here more info M Molbdnilo
#molbdnilo
An example of what you're most likely expected to do; define some useful sum types.
First, let's invent two ways to identify a person:
datatype Person = JustName of string
| NameAndNumber of string * int
datatype Identifier = Name of string
| Number of int
then you can get an Identifier for a Person:
fun identifier (JustName n) = Name n
| identifier (NameAndNumber (_, i)) = Number i
Let's test with some people:
- val people = [JustName "A", NameAndNumber ("B", 23), JustName "C", NameAndNumber ("D", 22)];
val people =
[JustName "A",NameAndNumber ("B",23),JustName "C",NameAndNumber ("D",22)]
: Person list
- map identifier people;
val it = [Name "A",Number 23,Name "C",Number 22] : Identifier list

Python 3 OOP - How to get names by first letter from an attribute list (Object Instance)

guys! I have a class ('Student') with 3 attributes ('name', 'id', 'gpa'). Then I have a list ('students') of objects of that class. I need to save to another list all instances of 'students' based on the first letter ('key') of its attribute list 'name'. So the new list should have 'students.name', 'students.id', 'students.gpa' for each 'name' that starts with the 'key'.
I have tried studentsNames = filter(lambda x: x.startswith(key), students) But the list ('studentsNames') comes up empty, even though there are names starting with the 'key'.
This is a sample of the code. Full class Student is here:https://github.com/lelecarabina/python3/blob/master/Student.py and full code below is here: https://github.com/lelecarabina/python3/blob/master/StudentFinder.py
...
#Create new Student object students
students = [Student((),(),())] * numStudents
print("All Students:")
# Initialize List of Student 'students' with **CONSTRUCTOR** and Print
for x in range(numStudents):
students[x] = (Student(names[x], (1101 + x), (gpas[rand]))) # constructor
print(students[x].getName(), students[x].getId(), students[x].getGpa())
#prompt user for input
key = input("\nEnter the first letter of student's name: ")
for x in range(len(students)):
studentsNames = [item for item in students if students[x].name[0] == key]
#print(studentsNames)
#print sorted list header
print("Students names starting with '{}'".format(key.upper()))
#loop through sorted list
for x in range(numStudents):
#end loop if no student's names matches user's input
if studentsNames == "":
print("NOT FOUND")
break
# end if statement
#print sorted list is student's name matches user's input, along with name's id and gpa
for name in studentsNames:
if name == students[x].name:
print(" Name: {} -> ID: {} -> GPA: {}".format(students[x].name, students[x].id, students[x].gpa))
# end if statement
# end for each loop
# end for loop
#message to user, ending program
print("Program Ended.")
It should print:
Name: ... -> ID: ... -> GPA: ... where dots are the info pulled from 'students'.
But it prints:
"Students names starting with 'L'
Program Ended."
Please help.
I. Figured. It. Out.
I needed students[x].name[0] == key.upper() instead of just students[x].name[0] == key because all names in the list start with capitals...
:(
Final code snippet:
`#prompt user for input
key = input("\nEnter the first letter of student's name: ")
#look for key in students.name list...
for x in range(len(students)):
#if key found...
if students[x].name[0] == key.upper():
#add student record to studentsNames list...
studentsNames.append(students[x].name)
#loop through sorted list
print("Students names starting with '{}'".format(key.upper()))
for x in range(numStudents):
#end loop if no student's names matches key
if studentsNames == "":
print("NOT FOUND")
break
# end if statement
#print student records that matched key
for name in studentsNames:
if name == students[x].name:
print(" Name: {} -> ID: {} -> GPA: {}".format(students[x].name, students[x].id, students[x].gpa))
# end if statement
# end for each loop
# end for loop`

I need a code which sums different numbers

I got a very difficult assignment as I am new to python, I hope you will be able to help me.
I wrote this code:
def hours_per_student(student_course,course_hours):
new={}
for key in student_course.keys():
for val in student_course.values():
for m in range(len(val)):
if not new.has_key(key):
new[key]=course_hours[val[m]]
else:
new[key]=new[key]+course_hours[val[m]]
return new
for these dictionaries:
student_course = {'rina' : ['math', 'python'], 'yossi' : ['chemistry', 'biology'], 'riki' : ['python']}
course_hours = {'math' : 4, 'python' : 4, 'chemistry' : 6, 'biology' : 5}
And I need to get this:
hours_per_student(student_course, course_hours)
to return this:
{'rina': 8, 'yossi': 11, 'riki': 4}
But I keep getting identical numbers for each key.
You shouldn't be iterating over .values() if you're already iterating over .keys(), just use the key to get the value. Or where you have for m in len(val), just do for m in val and then reference m instead of val[m](the naming here stinks but I discuss that later). Python is much better at iteration than that. For instance, instead of the line
for val in student_course.values():
you should try something like
for courses in student_course[key]:
for course in courses:
if key not in new:
new[key] = course_hours[course]
else:
new[key] += course_hours[course]
Naming your variables intelligently will make it easier for you to keep track of what's happening. For example, each value in student_course is a list of courses, so you should name it that, not something ambiguous like val. Similarly, each element in courses is the name of a course, so name it as such.
Here you go:
solution = {student: sum([hours.get(course, 0) for course in s_courses]) for student, s_courses in student_course.items()}
Here are the things I found lacking in your code:
When iterating over your students, you could have just created a key for each of them, and then add the hours per course.
Naming variables so you understand what they mean is confused, refrain from using new, key or val.
You don't have to use keys() function, iterating a dictionary using for key in dictionary works the same way.
Here's a fixed code snippet:
def hours_per_student(students, course_hours):
total_hours = {}
for student in students:
courses = students[student]
total_hours[student] = 0
for course in courses:
total_hours[student] += course_hours[course]
return total_hours

how to convert all the values in a list into keys of a Dictionary in Py2.7

I've below lists,
lists=[ ['arya','egg','milk','butter','bread'],
['Jon','butter','pastrie','yogurt','beer'],
['bran','beer','milk','banana','apples'],]
Each list has values in which the first value is the name of a person and rest of all are some food items. I've a task where I've to create a dictionary with these food items as keys and the person as a value as shown below
dict = { 'egg' : set(['arya']),
'milk': set(['arya','bran']),
'butter' : set(['arya','jon']),
'bread' : set(['arya']),
'pastrie' : set(['jon']),
'milk' : set(['bran'])
} # few keys omitted
This is what I did and stopped, dont know how to proceed further,
food,person = [],[]
for i in lists:
food.append(i[1:])
person.append(i[0])
I was able to seperate the first value of each list and append it to a list
and same with food.
Dont know how to proceed further.
started learning python, Any input is highly helpful. kindly share one or two lines of explanation to enlighten this newbie !
Thank you so much.
Using dictionary method setdefault is helpful here.
You of course don't nee to set the slices to a variable, but it makes it easier to read.
d = {}
for l in lists:
name = l[0]
items = l[1:]
for item in items:
d.setdefault(item, set()).add(name)
Use a collections.defaultdict:
lists = [['arya', 'egg', 'milk', 'butter', 'bread'],
['Jon', 'butter', 'pastrie', 'yogurt', 'beer'],
['bran', 'beer', 'milk', 'banana', 'apples']]
from collections import defaultdict
d = defaultdict(set)
for sub in lists:
for v in sub[1:]:
d[v].add(sub[0])
print(d)
Output:
defaultdict(<class 'set'>,
{'bread': {'arya'}, 'yogurt': {'Jon'}, 'beer': {'Jon', 'bran'},
'banana': {'bran'}, 'butter': {'Jon', 'arya'}, 'milk': {'arya',
'bran'}, 'pastrie': {'Jon'}, 'egg': {'arya'}, 'apples': {'bran'}})
For python3 the syntax is a little nicer:
from collections import defaultdict
d = defaultdict(set)
for name, *rest in lists:
for v in rest:
d[v].add(name)

Filter a list of lists

I would like to know how to filter a whole list out of list of lists
Example: [ ["Bob", "Baker", "male", "70000"],
["Alice", "Allen", "female", "82000"] ]
And now I would like to filter the list which contains female. So output would be:
["Alice", "Allen", "female", "82000"]
Thanks
Ankur's answer will certainly solve your problem, but I would like to make a suggestion that could make your life easier. It seems that you're storing all your data as strings in lists, but really what you'd like is a data type that could hold all this data in a more organized fashion, which can be done using Haskell data types, something like:
data Person = Person {
firstName :: String,
lastName :: String,
gender :: String,
salary :: String
} deriving (Eq, Show)
Then you could easily sort your data with filter (("female" ==) . gender) a. While this is a bit more code up front, later on if you were to add a "title" field for "Mr", "Mrs", etc, then it wouldn't matter if you added it at as the first field or the last field, this code would still work. Also, if for whatever reason you had an invalid value like ["Bob", "Baker", "male", "70000", "female"], Ankur's solution would give you an incorrect result, but with a custom data type, this would not even compile.
You could further improve your data structure with a few tweaks. I would suggest making a data type for gender, and then use Int or Double for the salary field, so you would have
data Gender = Male | Female deriving (Eq, Show, Read)
data Person = Person {
firstName :: String,
lastName :: String,
gender :: Gender,
salary :: Int
} deriving (Eq, Show)
filtGender :: Gender -> [Person] -> [Person]
filtGender gend people = filter ((gend ==) . gender) people
main :: IO ()
main = do
let people = [Person "Bob" "Baker" Male 70000,
Person "Alice" "Allen" Female 82000]
putStr "The females are: "
print $ filtGender Female people
putStr "The males are: "
print $ filtGender Male people
Prelude> let a = [ ["Bob", "Baker", "male", "70000"], ["Alice", "Allen", "female", "82000"] ]
Prelude> filter (elem "female") a
[["Alice","Allen","female","82000"]]