Slicing python list into new python lists - python

I tried to do a slice a list into three new lists but seems my method is problematic. Can you guys help me to see how I should do it? Thank you!
quiz = [[91, 94, 38, 48, 70, 85, 94, 59], [78, 96, 90, 55, 77, 82, 94, 60], [99, 94, 82, 77, 75, 89, 94, 93], [49, 92, 75, 48, 80, 95, 99, 98]]
midterm = []
final = []
I tried to make quiz to have the first five number of the list, midterm then have the next two, and final has the last number of the list:
quiz = [[91, 94, 38, 48, 70,], [78, 96, 90, 55, 77], [99, 94, 82, 77, 75,], [49, 92, 75, 48, 80]]
midterm = [[85, 94,],[82, 94,], [89, 94,], [95, 99,]]
final = [[59], [60], [93], [98]]
And here is my code:
quiz = [[91, 94, 38, 48, 70, 85, 94, 59], [78, 96, 90, 55, 77, 82, 94, 60], [99, 94, 82, 77, 75, 89, 94, 93], [49, 92, 75, 48, 80, 95, 99, 98]]
midterm = quiz[5:2]
final = midterm[5:1]

midterm = [i[5:7] for i in quiz]
final = [i[7:] for i in quiz]
quiz = [i[:5] for i in quiz]
How this works:
[ ] is a condensed version of a for loop.
For example, the above code is the same as the following:
for i in quiz:
midterm.append(i[5:7])
for i in quiz:
final.append(i[7:])
tmp = []
for i in quiz:
tmp.append(i[:5])
quiz = tmp
Which pretty much iterates through all of the elements in quiz and takes the two and the one and the five for the separate arrays. What you were doing wrong is that you did not treat quiz as a two dimensional array, but as a one dimensional array.
Your current code takes the second through fifth elements of the array quiz for midterm, which happen to be the second through fifth arrays of integers, not the second through fifth integers in each array in quiz.

here you go: using list comprehension
>>> quiz = [[91, 94, 38, 48, 70, 85, 94, 59], [78, 96, 90, 55, 77, 82, 94, 60], [99, 94, 82, 77, 75, 89, 94, 93], [49, 92, 75, 48, 80, 95, 99, 98]]
>>> new_quiz = [ x[:5] for x in quiz ]
>>> mid_term = [ x[5:7] for x in quiz ]
>>> final = [ x[-1:] for x in quiz ]
>>> new_quiz
[[91, 94, 38, 48, 70], [78, 96, 90, 55, 77], [99, 94, 82, 77, 75], [49, 92, 75, 48, 80]]
>>> mid_term
[[85, 94], [82, 94], [89, 94], [95, 99]]
>>> final
[[59], [60], [93], [98]]

Related

How to round inside a list using f string

I want to round some numbers inside of a list by using f-string, but it returns
unsupported format string passed to list.__format__
This is my code
IS_gradebooks = [['ISOM2020', [59, 100, 80, 55, 95, 87, 95, 98, 74, 69, 92, 94, 75, 97, 43, 57]],
['ISOM3400', [98, 73, 45, 88, 72, 94, 82, 100, 89, 52]],
['ISOM3600', [24, 44, 100, 81, 91, 93, 87, 72, 55]],
['ISOM4200', [90, 56, 78, 67, 90, 93]]
]
bruh=IS_gradebooks
for i in range(len(bruh)):
a=sum(bruh[i][1])/len(bruh[i][1])
bruh[i][1]=a
print(f"{bruh:.2f}")
You can change the variable bruh[i][1] to "{0:.2f}".format(a) and print that variable inside the loop:
for i in range(len(bruh)):
a=sum(bruh[i][1])/len(bruh[i][1])
bruh[i][1]="{0:.2f}".format(a)
print(bruh[i])

Advanced 3d numpy array slicing with alternation

So, I want to slice my 3d array to skip the first 2 arrays and then return the next two arrays. And I want the slice to keep following this pattern, alternating skipping 2 and giving 2 arrays etc.. I have found a solution, but I was wondering if there is a more elegant way to go about this? Preferably without having to reshape?
arr = np.arange(1, 251).reshape((10, 5, 5))
sliced_array = np.concatenate((arr[2::4], arr[3::4]), axis=1).ravel().reshape((4, 5, 5))
You can use boolean indexing using a mask that repeats [False, False, True, True, ...]:
import numpy as np
arr = np.arange(1, 251).reshape((10, 5, 5))
mask = np.arange(arr.shape[0]) % 4 >= 2
out = arr[mask]
out:
array([[[ 51, 52, 53, 54, 55],
[ 56, 57, 58, 59, 60],
[ 61, 62, 63, 64, 65],
[ 66, 67, 68, 69, 70],
[ 71, 72, 73, 74, 75]],
[[ 76, 77, 78, 79, 80],
[ 81, 82, 83, 84, 85],
[ 86, 87, 88, 89, 90],
[ 91, 92, 93, 94, 95],
[ 96, 97, 98, 99, 100]],
[[151, 152, 153, 154, 155],
[156, 157, 158, 159, 160],
[161, 162, 163, 164, 165],
[166, 167, 168, 169, 170],
[171, 172, 173, 174, 175]],
[[176, 177, 178, 179, 180],
[181, 182, 183, 184, 185],
[186, 187, 188, 189, 190],
[191, 192, 193, 194, 195],
[196, 197, 198, 199, 200]]])
Since you want to select, and skip, the same numbers, reshaping works.
For a 1d array:
In [97]: np.arange(10).reshape(5,2)[1::2]
Out[97]:
array([[2, 3],
[6, 7]])
which can then be ravelled.
Generalizing to more dimensions:
In [98]: x = np.arange(100).reshape(10,10)
In [99]: x.reshape(5,2,10)[1::2,...].reshape(-1,10)
Out[99]:
array([[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79]])
I won't go on to 3d because the display will be longer, but it should be straight forward.

How can I print the name of students with more than 50 points in all DS?

I have a several lists and dictionaries showing student names and scores.
How can I print the number of students and their names who have more than 50 points in all DS ?
students = ['Sara', 'Zineb', 'Mohamed', 'Ali', 'Khadija',
'Idriss', 'Najat', 'Nadia', 'Marouane', 'Ahmed']
scores = {'DS': [[36, 58, 46, 96, 9, 82, 83, 66, 35, 47],
[46, 50, 55, 21, 22, 76, 51, 90, 96, 48],
[56, 54, 53, 17, 31, 74, 11, 53, 98, 67],
[77, 38, 8, 74, 39, 39, 52, 66, 38, 86],
[93, 21, 7, 33, 10, 97, 48, 96, 24, 7],
[97, 98, 95, 75, 64, 9, 48, 51, 45, 82]],
'TP': [[48, 63, 98, 47, 25, 90, 100, 21, 41, 44],
[73, 79, 78, 39, 11, 100, 57, 96, 13, 99]]}
There are 10 students, and the there are 10 integers in each DS list.
If we want a set of students who scored more than 50 on each: we can (1) create a set of all students, (2) iterate over the lists, and (3) discard students from the set if they scored less than 50. (4) The remaining value in the set tells us that one student ('Nadia') scored more than 50 on all:
more_than_50 = set(students)
for score_list in scores['DS']:
for student, score in zip(students, score_list):
if score < 50:
more_than_50.discard(student)
print(len(more_than_50), more_than_50)
1 {'Nadia'}
You can try with this simple methods :
for i in len(students):
count=0
for row in scores['DS']:
if row[i]>50:
count+=1
if count==len(scores):#if all the grades > 50
print(students [i])

cant return a new list in binary search python different code

I'm a beginner in python , and I am doing the binary search task, I'm trying a different code than what it is common. My issue is that I can't return a new binary list. In the first time the function is working as it suppose to be, but for the second time the function isn't return the new list.
My Code:
import random, math
user_choice=random.randint(0,100)
print (user_choice)
max=100
number_elements=50
number_list=random.sample(range(max), number_elements)
sort_list=sorted(number_list)
print (sort_list)
count=0
limit=int(math.sqrt(number_elements))
# divide by 2 the length of the number_list
def divide_list(sort_list):
global count,number_elements
number_elements=int(number_elements//2)
count += 1
half=len(sort_list)//2
if user_choice <= sort_list[number_elements] :
sort_list=sort_list[:half]
print(sort_list)
else :
sort_list=sort_list[half:]
print(sort_list)
return sort_list
while len(sort_list)==0 or count <=limit:
max /= 2
divide_list(sort_list)
Output :
99
[5, 6, 8, 9, 14, 15, 17, 18, 19, 22, 23, 24, 26, 27, 28, 34, 35, 36, 38, 39, 40, 41, 44, 46, 47, 48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99],
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
[48, 50, 51, 53, 54, 55, 56, 57, 58, 61, 63, 64, 65, 67, 68, 69, 75, 76, 80, 81, 86, 90, 96, 97, 99]
Thanks for your help.
Your function is returning the list but you are not storing/updating it.
Solution:
Change the line divide_list(sort_list) to sort_list = divide_list(sort_list).
Explanation:
When you are updating the variable sort_list inside the function before printing (the line --> sort_list=sort_list[half:]), it is updating the variable sort_list associated to that function call and not the global variable sort_list. So by storing the return value in the global variable (as given in my solution), your list gets updated and passes the updated list next time the function is called.

Working with a list, performing arithmetic logic in Python

Suppose I have made a large list of numbers, and I want to make another one which I will add, pairwise, with the first list.
Here's the first list, A:
[109, 77, 57, 34, 94, 68, 96, 72, 39, 67, 49, 71, 121, 89, 61, 84, 45, 40, 104, 68, 54, 60, 68, 62, 91, 45, 41, 118, 44, 35, 53, 86, 41, 63, 111, 112, 54, 34, 52, 72, 111, 113, 47, 91, 107, 114, 105, 91, 57, 86, 32, 109, 84, 85, 114, 48, 105, 109, 68, 57, 78, 111, 64, 55, 97, 85, 40, 100, 74, 34, 94, 78, 57, 77, 94, 46, 95, 60, 42, 44, 68, 89, 113, 66, 112, 60, 40, 110, 89, 105, 113, 90, 73, 44, 39, 55, 108, 110, 64, 108]
And here's B:
[35, 106, 55, 61, 81, 109, 82, 85, 71, 55, 59, 38, 112, 92, 59, 37, 46, 55, 89, 63, 73, 119, 70, 76, 100, 49, 117, 77, 37, 62, 65, 115, 93, 34, 107, 102, 91, 58, 82, 119, 75, 117, 34, 112, 121, 58, 79, 69, 68, 72, 110, 43, 111, 51, 102, 39, 52, 62, 75, 118, 62, 46, 74, 77, 82, 81, 36, 87, 80, 56, 47, 41, 92, 102, 101, 66, 109, 108, 97, 49, 72, 74, 93, 114, 55, 116, 66, 93, 56, 56, 93, 99, 96, 115, 93, 111, 57, 105, 35, 99]
How might I generate the arithmetic addition logic, processing each pairwise value one by one (A[0] and B[0], through A[99], B[99]) and producing the list C (A[0] + B[0] through A[99]+ B[99])?
result = [(x + y) for x, y in itertools.izip(A, B)]
Or:
result = map(operator.add, itertools.izip(A, B))
Here is two possible options:
Use list comprehension.
Use NumPy.
I will be using shortened versions of your lists for convenience, and the element-wise sum will go into c.
List comprehension
a = [109, 77, 57, 34, 94, 68, 96]
b = [35, 106, 55, 61, 81, 109, 82]
c = [a_el + b_el for a_el,b_el in zip(a, b)]
NumPy
import numpy as np
a = np.array([109, 77, 57, 34, 94, 68, 96])
b = np.array([35, 106, 55, 61, 81, 109, 82])
c = a + b
With a list comprehension:
C = [A[i]+ B[i] for i in range(len(A))]
And even safer:
C = [A[i]+ B[i] for i in range(len(A)) if len(A) == len(B)]

Categories