So, for fun and practice I have been following along a college friend and their more advanced programming class and tackling assignments they are assigned to ready myself for the same Python class. I'm now at dictionaries and tuples sorting them based on the least to greatest number in an assigned dictonary. so far I have this code:
cityRevenues = {'Alabaster':[40,50,23,18], 'Anniston':[56,78,34,11],
'Athens':[40,34,18,30],'Auburn':[55,67,23,11],
'Decatur':[44,23,56,11],'Florence':[55,67,33,23],'Gadsden':[45,67,54,77]}
a = (sorted(cityRevenues.items(), key=lambda x: x[1]))
print('Sort the cities by their Quarter 1 Revenues.')
print("")
print(a)
print("")
b = (sorted(cityRevenues.items(), key=lambda x: x[1][1]))
print('Sort the cities by their Quarter 2 Revenues.')
print("")
print(b)
print("")
c = (sorted(cityRevenues.items(), key=lambda x: x[1][2]))
print("Sort the cities by their Quarter 3 Revenues.")
print("")
print(c)
print("")
d = (sorted(cityRevenues.items(), key=lambda x: x[1][3]))
print("Sort the cities by their Quarter 4 Revenues.")
print("")
print(d)
print("")
which gives the output:
Sort the cities by their Quarter 1 Revenues.
[('Athens', [40, 34, 18, 30]), ('Alabaster', [40, 50, 23, 18]), ('Decatur', [44, 23, 56, 11]), ('Gadsden', [45, 67, 54, 77]), ('Auburn', [55, 67, 23, 11]), ('Florence', [55, 67, 33, 23]), ('Anniston', [56, 78, 34, 11])]
Sort the cities by their Quarter 2 Revenues.
[('Decatur', [44, 23, 56, 11]), ('Athens', [40, 34, 18, 30]), ('Alabaster', [40, 50, 23, 18]), ('Auburn', [55, 67, 23, 11]), ('Florence', [55, 67, 33, 23]), ('Gadsden', [45, 67, 54, 77]), ('Anniston', [56, 78, 34, 11])]
Sort the cities by their Quarter 3 Revenues.
[('Athens', [40, 34, 18, 30]), ('Auburn', [55, 67, 23, 11]), ('Alabaster', [40, 50, 23, 18]), ('Florence', [55, 67, 33, 23]), ('Anniston', [56, 78, 34, 11]), ('Gadsden', [45, 67, 54, 77]), ('Decatur', [44, 23, 56, 11])]
Sort the cities by their Quarter 4 Revenues.
[('Auburn', [55, 67, 23, 11]), ('Decatur', [44, 23, 56, 11]), ('Anniston', [56, 78, 34, 11]), ('Alabaster', [40, 50, 23, 18]), ('Florence', [55, 67, 33, 23]), ('Athens', [40, 34, 18, 30]), ('Gadsden', [45, 67, 54, 77])]
I managed to sort them based on the least to greatest in each tuple, but I do not know how to code it to where it shows only the one value that is greatest in the tuple. i.e.:
Sort the cities by their Quarter 1 Revenues.
[('Athens', [40]), ('Alabaster', [40]), ('Decatur', [44]), ('Gadsden', [45]), ('Auburn', [55]), ('Florence', [55]), ('Anniston', [56])]
How would I go about having the specific tuple values be the only ones printed?
Try the following:
# To get the first value of the list for the city, use pair[1][0].
# You can get the second value of the list for the city by using pair[1][1]
# An so on...
>>> d = {pair[0]: [pair[1][0]] for pair in sorted(cityRevenues.items(), key=lambda x: x[1][3])}
>>> list(d.items())
[('Gadsden', [45]), ('Athens', [40]), ('Anniston', [56]), ('Alabaster', [40]), ('Florence', [55]), ('Auburn', [55]), ('Decatur', [44])]
Since the largest element is at the end of the list, you can use index -1
e.g.
cityRevenues = {'Alabaster':[40,50,23,18], 'Anniston':[56,78,34,11],
'Athens':[40,34,18,30],'Auburn':[55,67,23,11],
'Decatur':[44,23,56,11],'Florence':[55,67,33,23],'Gadsden':[45,67,54,77]}
a = (sorted(cityRevenues.items(), key=lambda x: x[1]))
print('Sort the cities by their Quarter 1 Revenues.')
print("\n")
print(a[-1])
print("\n")
It will give
('Anniston', [56, 78, 34, 11])
You print the last item in the list:
print (a[-1])
Format as desired.
By the way, you can make this code much shorter if you use the same variable name for each sorted list, and also collect your keys in a list you can index according to the input choice.
Related
I have a list of key:
list_date = ["MON", "TUE", "WED", "THU","FRI"]
I have many lists of values that created by codes below:
list_value = list()
for i in list(range(5, 70, 14)):
list_value.append(list(range(i, i+10, 3)))
Rules created that:
first number is 5, a list contains 4 items has value equal x = x + 3, and so on [5, 8, 11,1 4]
the first number of the second list equal: x = 5 + 14, and value inside still as above x = x +3
[[5, 8, 11, 14], [19, 22, 25, 28], [33, 36, 39, 42], [47, 50, 53, 56], [61, 64, 67, 70]]
I expect to obtain a dict like this:
collections = {"MON":[5, 8, 11, 14], "TUE" :[19, 22, 25, 28], "WED":[33, 36, 39, 42], "THU":[47, 50, 53, 56], "FRI":[61, 64, 67, 70]}
Then, I used:
zip_iterator = zip(list_date, list_value)
collections = dict(zip_iterator)
To get my expected result.
I tried another way like using lambda function
for i in list(range(5, 70, 14)):
list_value.append(list(range(i,i+10,3)))
couple_start_end[lambda x: x in list_date] = list(range(i, i + 10, 3))
And the output is:
{<function <lambda> at 0x000001BF7F0711F0>: [5, 8, 11, 14], <function <lambda> at 0x000001BF7F071310>: [19, 22, 25, 28], <function <lambda> at 0x000001BF7F071280>: [33, 36, 39, 42], <function <lambda> at 0x000001BF7F0710D0>: [47, 50, 53, 56], <function <lambda> at 0x000001BF7F0890D0>: [61, 64, 67, 70]}
I want to ask there is any better solution to create lists of values with the rules above? and create the dictionary collections without using the zip method?
Thank you so much for your attention and participation.
Sure, you can use enumerate but I wouldn't say it is in anyway better or worse than the zip based solution:
collections = {}
for idx, key in enumerate(list_keys):
collections[key] = list_value[idx]
print(collections)
Output:
{'MON': [5, 8, 11, 14], 'TUE': [19, 22, 25, 28], 'WED': [33, 36, 39, 42], 'THU': [47, 50, 53, 56], 'FRI': [61, 64, 67, 70]}
Further, you don't need to create the value list separately, you can create the dictionary as you go along:
list_keys = ["MON", "TUE", "WED", "THU","FRI"]
collections = {}
for idx, start in enumerate(range(5, 70, 14)):
collections[list_keys[idx]] = [i for i in range(start, start+10, 3)]
print(collections)
I like to form a dictionary with two lists, header as the key and score as the values:
#data
header= ["math","science","english"]
score = [80,95,75,81,22,90,20,55,99]
#my attempt
d={}
for i in header:
print(i)
for j in score:
print(j)
Desired output is
{("math":80, 81, 20),("science":95,22,55),("english":75,90,99)}
>>> {k: score[i::3] for i, k in enumerate(header)}
{'math': [80, 81, 20], 'science': [95, 22, 55], 'english': [75, 90, 99]}
We can make use of zip in this scenario.
groups = [score[i::3] for i in range(0, len(header))]
dict(zip(header, groups))
{'english': [75, 90, 99], 'math': [80, 81, 20], 'science': [95, 22, 55]}
Assuming you want your output to be a valid dictionary. Then try this.
dict(zip(header,zip(*[score[i:i+3] for i in range(0,len(score),3)])))
# {'math': (80, 81, 20), 'science': (95, 22, 55), 'english': (75, 90, 99)}
You have:
>>> header= ["math","science","english"]
>>> score = [80,95,75,81,22,90,20,55,99]
The first idea is to use zip, but zip stops when the shortest of the two lists is exhausted:
>>> dict(zip(header, score))
{'math': 80, 'science': 95, 'english': 75}
You have to use a second zip to group the scores:
>>> n = len(header)
>>> L = list(zip(*(score[i*n:(i+1)*n] for i in range(n))))
>>> L
[(80, 81, 20), (95, 22, 55), (75, 90, 99)]
And then to zip the header and the grouped scores:
>>> dict(zip(header, L))
{'math': (80, 81, 20), 'science': (95, 22, 55), 'english': (75, 90, 99)}
You should try to divide your problem into multiple smaller problems. Here are two links to related questions and their answers here on Stack Overflow:
How to Split Python list every Nth element
Choose one of the multiple possible solutions for a slice_per function there, so you'll get:
>>> header = ["math", "science", "english"]
>>> score = [80, 95, 75, 81, 22, 90, 20, 55, 99]
>>> def slice_per(source, step):
... return [source[i::step] for i in range(step)]
...
>>> slice_per(score, len(header))
[[80, 81, 20], [95, 22, 55], [75, 90, 99]]
Convert two lists into a dictionary
Combine the slices with your headers:
>>> dict(zip(header, slice_per(score, len(header))))
{'math': [80, 81, 20], 'science': [95, 22, 55], 'english': [75, 90, 99]}
you could use a dictionary comprehension and the buil-in function and enumerate:
step = len(header)
{k : score[i::step] for i, k in enumerate(header)}
output:
{'math': [80, 81, 20], 'science': [95, 22, 55], 'english': [75, 90, 99]}
or you can use numpy:
import numpy as np
dict(zip(header, np.array(score).reshape(3,3).T.tolist()))
output:
{'math': [80, 81, 20], 'science': [95, 22, 55], 'english': [75, 90, 99]}
if you want to use for loops:
result = {}
for i in range(len(score) // len(header)):
for j, h in enumerate(header):
result.setdefault(h, []).append(score[i * len(header) + j])
result
output:
{'math': [80, 81, 20], 'science': [95, 22, 55], 'english': [75, 90, 99]}
I am trying to test the function map with the method append and got a wrong output.
Code
numbers = [
[34, 63, 88, 71, 29],
[90, 78, 51, 27, 45],
[63, 37, 85, 46, 22],
[51, 22, 34, 11, 18]
]
numbers_tmp = []
def mean_append(num_list):
numbers_tmp.append(sum(num_list) / len(num_list))
return numbers_tmp
print(list(map(mean_append, numbers)))
Expected output
[57.0, 58.2, 50.6, 27.2]
Actual output
[
[57.0, 58.2, 50.6, 27.2],
[57.0, 58.2, 50.6, 27.2],
[57.0, 58.2, 50.6, 27.2],
[57.0, 58.2, 50.6, 27.2]
]
Built-in map works on each value in an iterable. So your function should include logic which can be applied to each sublist:
def mean_calculator(num_list):
return sum(num_list) / len(num_list)
res = list(map(mean_calculator, numbers))
print(res)
[57.0, 58.2, 50.6, 27.2]
Alternatively, you can use statistics.mean from the standard library:
from statistics import mean
res = list(map(mean, numbers))
map returns one output object for each object in the input sequence. Your input sequence has 4 objects, so the output has 4 objects. They're all same since your function always returns same numbers_tmp object. To fix the problem stop using global variables in map.
numbers = [[34, 63, 88, 71, 29], [90, 78, 51, 27, 45], [63, 37, 85, 46, 22], [51, 22, 34, 11, 18]]
def mean_append(num_list):
return sum(num_list) / len(num_list)
print(list(map(mean_append, numbers)))
I'm trying to find the longest increasing subsequence from the python list i'm passing. The final dictionary structure should look something like this:
Expected structure
subsequence_dict={ 0:[15], 1:[15,27], 2:[14],3:[15,27,38],4:[14,26],5:[15,27,38,55],6:[15,27,38,46],7:[15, 27, 38, 55, 65, 85]}
Output:
{0: [15, 27, 38, 55, 65, 85], 1: [15, 27, 38, 55, 65, 85], 2: [14, 26, 46], 3: [15, 27, 38, 55, 65, 85], 4: [14, 26, 46], 5: [15, 27, 38, 55, 65, 85], 6: [14, 26, 46], 7: [15, 27, 38, 55, 65, 85], 8: [15, 27, 38, 55, 65, 85]}
As looking at the key 0 in my output it looks there is some mutability issue.
For every value of i in the main function there should be a new key in the dict which has value as list coming from longest_subsequence function.
from copy import deepcopy
def longest_subsequence(dict_elent,subsequence_dict):
"""
:param dict_elent: Dictionary element to which the longest list last element to be compared
:param subsequence_dict:
:return: List
"""
x=subsequence_dict.values()
sorted_list = sorted(x, reverse=True)
flag=False
for sublist in sorted_list:
if sublist[-1]<dict_elent:
sublist.append(dict_elent)
flag=True
break
if flag==True:
return sublist
else:
return [dict_elent]
def main(d,subsequence_dict):
for i in range(len(d)):
if i==0 :
subsequence_dict[i]=[d[i]]
else:
subsequence_dict.update({i: longest_subsequence(d[i],subsequence_dict)})
if __name__ == '__main__':
d=[15,27,14,38,26,55,46,65,85]
subsequence_dict={}
main(d,subsequence_dict)
print(subsequence_dict)
I am trying to write a function named studentGrades(gradeList) that takes a nested list and returns a list with the average score for each student.
An example would be:
grades= [['Student','Quiz 1','Quiz 2','Quiz 3','Final'],
['John', 100, 90, 80, 90],
['McVay', 88, 99, 11, 15],
['Rita', 45, 56, 67, 89],
['Ketan', 59, 61, 67, 32],
['Saranya', 73, 79, 83, 45],
['Min', 89, 97, 101, 100]]
studentGrades(grades)
# Sample output below
>>> [90, 53, 64, 54, 70, 96]
I don't know how to do this using a nested loop. Any help or guidance is appreciated.
Incase you need a one liner
[int(sum(i[1:])/len(i[1:])) for i in grades[1:]]
Output:
[90, 53, 64, 54, 70, 96]
As I suggested in the comments, you can also use a dictionary for that. Dictionaries are basically made for situations like these and if you want to use your data any further, they might prove beneficial.
You would first have to convert your current structure, which I assumed is fixed in the sense that you have a "header" in grades, and then lists of the form [name,points..]. You can do:
grades= [['Student','Quiz 1','Quiz 2','Quiz 3','Final'],
['John', 100, 90, 80, 90],
['McVay', 88, 99, 11, 15],
['Rita', 45, 56, 67, 89],
['Ketan', 59, 61, 67, 32],
['Saranya', 73, 79, 83, 45],
['Min', 89, 97, 101, 100]]
gradedict = {}
for rows in grades[1:]:
gradedict[rows[0]] = rows[1:]
To initialize the dictionary. Then the following function:
def studentGrades(gradedict):
avgdict = {}
for key,lst in gradedict.items():
avgdict[key] = sum(lst)/len(lst)
return avgdict
Returns another dictionary with the corresponding averages. You could loop through the names, i.e. the keys, of either of those to print that. For example:
gradedict = studentGrades(gradedict)
for x in gradedict:
print("student ",x, " achieved an average of: ",gradedict[x])
which is just to show you how to access the elements. you can of course also loop through keys,items as I did in the function.
Hope this helps.
You can do something like this:
def studentGrades(a):
# return [sum(k[1:])/(len(k)-1) for k in a[1:]]
# Or
l = len(a[0]) - 1 # how many quizzes, thanks to #Mad Physicist
return [sum(k[1:])/l for k in a[1:]]
grades= [['Student','Quiz 1','Quiz 2','Quiz 3','Final'],
['John', 100, 90, 80, 90],
['McVay', 88, 99, 11, 15],
['Rita', 45, 56, 67, 89],
['Ketan', 59, 61, 67, 32],
['Saranya', 73, 79, 83, 45],
['Min', 89, 97, 101, 100]]
final = studentGrades(grades)
print(final)
Output:
[90, 53, 64, 54, 70, 96]
Why not just use pandas?
df = pd.DataFrame(grades).set_index(0).iloc[1:].mean(axis=1).astype(int)
Output:
John 90
McVay 53
Rita 64
Ketan 54
Saranya 70
Min 96
or
list(df.values)
Output:
[90, 53, 64, 54, 70, 96]
grades= [['Student','Quiz 1','Quiz 2','Quiz 3','Final'],
['John', 100, 90, 80, 90],
['McVay', 88, 99, 11, 15],
['Rita', 45, 56, 67, 89],
['Ketan', 59, 61, 67, 32],
['Saranya', 73, 79, 83, 45],
['Min', 89, 97, 101, 100]]
def average(grades):
for m in grades[1:]:
t = m[1:]
l = len(t)
s = sum(t)
yield s//l
list(average(grades))