Mastering Python
Source: https://www.w3resource.com/python-exercises/python_100_exercises_with_solutions.php
Exercise 1:
Create a list with values ranging from 0 to 9.
soln
lists take in iterators
#my_list = [i for i in range(10)]
my_list = list(range(10))
my_list
output
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Exercise 2:
Convert a list of integers to a list of strings.
soln
map(function, iterable, *iterables)
map returns an iterator. it applies fn to an iterator with iterable args.
my_list_as_strs = list(map(str, my_list))
my_list_as_strs
output
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Exercise 3:
Multiply all elements in a list by 2.
soln
a very functional programming approach; manipulating data with subsequent functional transformations.
also, unusually I could not find any documentation on lambda expressions in the main Python Standard Library. I had to click into the tutorial and take a look at “more control flow tools”.
another_list = list(range(5))
times_two_list = list(map(lambda x: 2*x, another_list))
times_two_list
output
| 0 | 2 | 4 | 6 | 8 |
Exercise 4:
Extract all odd numbers from a list of integers.
soln
maps continue to be useful, however perhaps a filter will be a better idea here.
another_list = list(range(20))
odd_lists = list(filter(lambda x: x%2==1, another_list))
odd_lists
the modulo 2 case would equal 1 whenever an odd number was given. we’re spitting out the cases of which that was true:
output
| 1 | 3 | 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 |
Exercise 5:
Replace all odd numbers in a list with -1.
soln
we go back to a map for this one.
note that the ternary operator syntax is different to C/Java.
another_list = list(range(20))
odd_lists_minus_one = list(map(lambda x:-1 if x%2==1 else x, another_list))
odd_lists_minus_one
output
| 0 | -1 | 2 | -1 | 4 | -1 | 6 | -1 | 8 | -1 | 10 | -1 | 12 | -1 | 14 | -1 | 16 | -1 | 18 | -1 |
Exercise 6:
Convert a list of integers to a list of booleans where all non-zero values become True.
soln
note that in Python, true is actually True and false, False.
list_ints = list(range(15))
bool_list = list(map(lambda x: True if x != 0 else False, list_ints))
bool_list
output
| False | True | True | True | True | True | True | True | True | True | True | True | True | True | True |
Exercise 7:
Replace all even numbers in a list with their negative.
list_ints = list(range(15))
neg_list = list(map(lambda x: -x if x % 2 == 0 else x, list_ints))
neg_list
Exercise 8:
Create a 3x3 list of lists with random values and normalize it.
soln
crazy: notice that the randint bounds are <= and >=!
import random
random.seed(4)
def create_n_by_n_list(n):
return [[random.randint(0,n) for i in range(n)] for i in list(range(0,n))]
def normalise_list(l, n):
import numpy
return numpy.array(l) / n
my_list = create_n_by_n_list(6)
norm_list = normalise_list(my_list, 6)
print(norm_list)
output
I generalised the problem to nxn.
also I used numpy to skip a list comprehension.
[[0.16666667 0.33333333 0. 0.83333333 0.5 0.5 ]
[0.16666667 0. 0. 0. 0.5 0.66666667]
[0.33333333 1. 1. 0. 0.16666667 0.66666667]
[0.66666667 0.33333333 0.33333333 1. 0.16666667 1. ]
[0. 0.33333333 0.16666667 0. 1. 0.83333333]
[1. 0.33333333 1. 0.33333333 0.16666667 0.16666667]]
Exercise 9:
Calculate the sum of the diagonal elements of a 3x3 matrix (list of lists).
soln
import numpy
print(sum(numpy.diag(norm_list)))
Exercise 10:
Find the indices of non-zero elements in a list.
soln
this notation is illegal: lambda i, v:
new_list = list(range(-5, 4))
tuple_list = filter(lambda t: t[1] != 0, enumerate(new_list)) # filter correct tuples
out_list = [e[0] for e in tuple_list] # construct list of indices
out_list
output
fk that was hard.
| 0 | 1 | 2 | 3 | 4 | 6 | 7 | 8 |
Exercise 11:
Reverse a list.
soln
one thing to be careful of with the list.reverse() method is that the reversal happens “in-place”, i.e. on the object that the method was called on.
out_list.reverse() # no return value for this
print(out_list)
print(new_list) # defined in the last q
print(reversed(new_list)) # returns an iterator object
print(list(reversed(new_list)))
further, it must noted that all the above are “shallow-copies”, whilst they are fast, if the objects which constitute the list are mutable, then you could run into problems with the reversed list misbehaving later:
x = 6
a = 7
b = 8
var_list = [x, a, b]
print(f"var_list: {var_list}")
stable_list = var_list[::-1]
question_list = list(reversed(var_list))
x = 1
a = 2
b = 3
unstable_list = list(reversed(var_list))
print(question_list)
print(unstable_list)
print(stable_list)
now, notice that you STILL cannot see a difference! this is because your x,a,b variables are immutable; they are integers.
var_list: [6, 7, 8]
[8, 7, 6]
[8, 7, 6]
[8, 7, 6]
try this code
x = [6]
a = [7]
b = [8]
var_list = [x, a, b]
print(f"var_list: {var_list}")
stable_list = var_list[::-1]
question_list = list(reversed(var_list))
x.append(1)
a.append(2)
b.append(3)
unstable_list = list(reversed(var_list))
print(f"question_list: {question_list}")
print(f"unstable_list: {unstable_list}")
print(f"stable_list: {stable_list}")
ultimately, if you want a non-shallow copy you must use deepcopy
import copy
stable_list = copy.deepcopy(var_list)
print(f"stable_list: {stable_list}")
# and now, even if you mutate the lists, stable_list does not change but unstable_list will:
x.pop()
print(f"unstable_list: {unstable_list}")
print(f"still stable: {stable_list}")
Exercise 12:
Create a 3x3 identity matrix as a list of lists.
import numpy as np
print(np.eye(3))
Exercise 13:
Reshape a 1D list to a 2D list with 2 rows.
soln1
l = np.array(range(12))
print(l.reshape(2, -1))
output
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
soln2, no numpy
l = list(range(12))
x = [l[x:x+int(len(l)/2)] for x in range(0, len(l), int(len(l)/2))]
print(x)
output
terrific, well done!
[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]
Exercise 14:
Stack two lists vertically.
l1 = list(range(4))[::-1]
l2 = list(range(4))
l = [l1, l2]
print(l)
Exercise 15:
Get the common items between two lists.
shit, I accidentally got all the unique items by using sets
l1 = list(range(4))[::-1]
l2 = list(range(7))
l1.extend(l2)
s = list(set(l1))
print(s)
that’s okay, it’s not much different to find the duplicates; we can use the intersection method of sets
l1 = list(range(4))[::-1]
l2 = list(range(7))
dupes = list(set(l1).intersection(set(l2)))
# also, note that the intersection method can accept any iterable! thus this works too:
dupes = list(set(l1).intersection(l2))
print(dupes)
output
[0, 1, 2, 3]
Exercise 16:
Create a 5x5 list of lists with row values ranging from 0 to 4.
soln1
import random
random.seed(4)
n = 5
l = [ [random.randint(0,n-1) for i in range(n)] for i in range(n)]
print(l)
soln2
i believe we can accomplish the same thing more quickly with numpy:
import numpy
m = numpy.random.randint(5, size=(5,5))
print(m)
timing
import timeit
# Setup code for the list-comprehension approach
setup1 = """
import random
random.seed(4)
n = 5
"""
# The statement we want to time repeatedly
stmt1 = """
l = [[random.randint(0, n - 1) for i in range(n)] for j in range(n)]
"""
# Setup code for the NumPy approach
setup2 = """
import numpy
"""
# The statement we want to time repeatedly
stmt2 = """
m = numpy.random.randint(5, size=(5, 5))
"""
# Number of iterations to run timeit
iterations = 1_000_000
time1 = timeit.timeit(stmt=stmt1, setup=setup1, number=iterations)
time2 = timeit.timeit(stmt=stmt2, setup=setup2, number=iterations)
print(f"List comprehension approach: {time1:.6f} seconds")
print(f"NumPy approach: {time2:.6f} seconds")
Exercise 17:
Find the index of the maximum value in a list.
soln
max(max(l))
and for a single dimensional array (the above was 2d)
max(range(15))
however, the number of max calls is clearly dependent on the dimensionality. as such we can use numpy:
numpy.amax(l)
Exercise 18:
Normalize the values in a list between 0 and 1.
we can do it nakedly with the math library and implement softmax, which is defined in multi-variate calculus.
import math
my_list = list(range(7))
new_list = list(map(lambda x: math.exp(x) / sum(math.exp(y) for y in my_list), my_list))
print(new_list)
print(sum(new_list)) # checking it all sums to 1
import numpy as np
def softmax(x):
return np.exp(x) / sum(np.exp(x))
print(sum(softmax(my_list)))
print(softmax(my_list))
Exercise 19:
Calculate the dot product of two lists.
random.seed(4)
list_a = random.choices(range(10),k=10) # without numpy
list_b = random.choices(range(10),k=10)
print(list_a)
print(list_b)
dot_p = sum(list(map(math.prod, zip(list_a,list_b))))
print(dot_p)
Exercise 20:
Count the number of elements in a list within a specific range.
def count_elements_within_range(a, b, x):
return sum(a <= y <= b for y in x)
count_elements_within_range(5, 12, list(range(14))[5::3])
Exercise 21:
Find the mean of each row in a 2D list.
def average(l):
return sum(l)/len(l)
""" takes in list of lists
returns list of averages, one for each row
"""
def mean_list_of_rows(ml):
return [average(x) for x in ml]
my_list = [[1,2,3],[4,5],[3,3]]
mean_list_of_rows(my_list)
Exercise 22:
Create a random 4x4 list of lists and extract the diagonal elements.
import numpy as np
list_of_lists = np.random.randint(10, size=(4,4))
print(list_of_lists)
np.diag(list_of_lists)
Exercise 23:
Count the number of occurrences of a specific value in a list.
range_list = list(range(6))
range_list.count(4)
Exercise 24:
Replace all values in a list with the mean of the list.
range_list = list(range(6))
range_list = [average(range_list) for x in range_list]
print(range_list)
Exercise 25:
Find the indices of the maximum and minimum values in a list.
range_list = list(range(6))
print(range_list.index(min(range_list)))
print(range_list.index(max(range_list)))
you of course also have the numpy method, however that requires the overhead of converting to a numpy array first:
range_list = list(range(6))
print(np.argmin(range_list))
print(np.argmax(range_list))
Exercise 26:
Create a 2D list with 1 on the border and 0 inside.
# note this program only works for odd n
n = 3
mat = np.ones((n,n))
mat[n//2][n//2] = 0
print(mat)
Exercise 27:
Find the unique values and their counts in a list.
l1 = list(range(6))
l2 = list(range(2,7))
l1.extend(l2)
uniq = list(set(l1))
counts = {x: l1.count(x) for x in l1}
print(counts)
print(uniq)
Exercise 28:
Create a 3x3 list of lists with values ranging from 0 to 8.
nums = list(range(9))
ll_nums = [nums[x:x+3] for x in range(0,9,3)]
print(ll_nums)
Exercise 29:
Calculate the exponential of all elements in a list.
import math
nums = list(range(9))
nums = [math.exp(x) for x in nums]
print(nums)
Exercise 30:
Swap two rows in a 2D list.
import random
matrix = create_n_by_n_list(4)
print(matrix)
matrix[0], matrix[1] = matrix[1], matrix[0]
print(matrix)
Exercise 31:
Create a random 3x3 list of lists and replace all values greater than 0.5 with 1 and all others with 0.
soln
import random
random.seed(3)
print([[1 if random.random() > 0.5 else 0 for _ in range(3)] for _ in range(3)])
output
[[0, 1, 0], [1, 1, 0], [0, 1, 0]]
Exercise 32:
Find the indices of the top N maximum values in a list.
soln
top_n_idx = lambda x,n: list(list(zip(*sorted(enumerate(x), key=lambda x:x[1], reverse=True)))[0][:n:])
print(top_n_idx([1, 2, 6, 4], 3))
output
[2, 3, 1]
Exercise 33:
Calculate the mean of each column in a 2D list.
soln (oops sums over rows!)
mean_cols = lambda l: [sum(l[i]) / len(l) for i in range(len(l))]
n = 5
d2_list = [[random.randint(0,10) for _ in range(n)] for _ in range(n)]
print(mean_cols(d2_list))
soln (over cols)
mean_cols = lambda l: [sum(row[i] for row in l) / len(l) for i in range(len(l))]
n = 5
d2_list = [[random.randint(0,10) for _ in range(n)] for _ in range(n)]
print(mean_cols(d2_list))
Exercise 34:
Normalize the values in each column of a 2D list.
soln
random.seed(4)
mean_cols = lambda l: [
[l[r][c] / sum(l[i][c] for i in range(len(l[r])))
for c in range(len(l[r]))]
for r in range(len(l))
]
n = 5
d2_list = [[random.randint(0,10) for _ in range(n)] for _ in range(n)]
print("original matrix:", d2_list)
print(mean_cols(d2_list))
output
original matrix: [[3, 4, 1, 6, 7], [2, 1, 1, 0, 6], [8, 4, 0, 3, 8], [8, 5, 4, 2, 1], [4, 3, 0, 10, 4]]
[[0.12, 0.23529411764705882, 0.16666666666666666, 0.2857142857142857, 0.2692307692307692], [0.08, 0.058823529411764705, 0.16666666666666666, 0.0, 0.23076923076923078], [0.32, 0.23529411764705882, 0.0, 0.14285714285714285, 0.3076923076923077], [0.32, 0.29411764705882354, 0.6666666666666666, 0.09523809523809523, 0.038461538461538464], [0.16, 0.17647058823529413, 0.0, 0.47619047619047616, 0.15384615384615385]]
lessons
- you need be careful along the axis which you are computing index calculations on
- if you are going to use huge lambda functions, at least indent them and split them across multiple lines.
Exercise 35:
Concatenate two lists.
soln
l1 = list(range(5))
l2 = ['a', 'b', 'string']
l1.extend(l2)
print(l1)
output
[0, 1, 2, 3, 4, 'a', 'b', 'string']
Exercise 36:
Create a 2D list with random values and sort each row.
soln
import random
n = 3
sort_rows = lambda l: [sorted(row) for row in l]
print(sort_rows([[random.randint(0,n) for _ in range(n)] for _ in range(n)]))
output
[[0, 3, 3], [2, 2, 3], [0, 3, 3]]
Exercise 37:
Check if all elements in a list are non-zero.
soln(bad)
my_list = [random.randint(0,n) for _ in range(n)]
check_nonzero = lambda l: True if len(list(filter(lambda x: x == 0, l))) == 0 else False
print(my_list)
print(check_nonzero(my_list))
output
[3, 3, 3]
True
[3, 0, 3]
False
soln(good)
my_list = [random.randint(0,n) for _ in range(n)]
check_nonzero = lambda l: all(l)
print(my_list)
print(check_nonzero(my_list))
output
[0, 3, 2]
False
[3, 3, 3]
True
Exercise 38:
Find the indices of the maximum value in each row of a 2D list.
soln
my_list = [[random.randint(0,n+2) for _ in range(n)] for _ in range(n)]
max_idx_rows_as_list = lambda l: list(map(lambda x: x.index(max(x)), l))
print(my_list)
print(max_idx_rows_as_list(my_list))
output
[[2, 0, 5], [1, 2, 3], [0, 5, 0]]
[2, 2, 1]
Exercise 39:
Create a 2D list and replace all nan values with the mean of the list.
soln
my_list = [[random.randint(0,n+2) for _ in range(n)] for _ in range(n)]
max_idx_rows_as_list = lambda l: list(map(lambda x: x.index(max(x)), l))
print(my_list)
print(max_idx_rows_as_list(my_list))
output
Exercise 40:
Calculate the mean of each row in a 2D list ignoring nan values.
soln
import math
matrix = [[1, float('nan'), 3], [4, 5, float('nan')], [7, 8, 9]]
#row_means = [sum(x for x in row if not math.isnan(x)) / sum(1 for x in row if not math.isnan(x)) for row in matrix]
row_means = list(map(lambda x: sum(i for i in x if not math.isnan(i)) / sum(1 for i in x if not math.isnan(i)) , matrix))
print(row_means)
soln
[2.0, 4.5, 8.0]
lessons
to summon a nan, you may use float('nan'). or you may also use
n1 = float("nan")
n2 = float("Nan")
n3 = float("NaN")
n4 = float("NAN")
print n1, n2, n3, n4
from decimal import *
n1 = Decimal("nan")
n2 = Decimal("Nan")
n3 = Decimal("NaN")
n4 = Decimal("NAN")
print n1, n2, n3, n4
import math
n1 = math.nan
print(n1)
print(math.isnan(n1))
import numpy as np
n1 = np.nan
# Check if a value is NaN
print(np.isnan(n1))
furthermore, to sum across elements in an unknown dimensional array, with each of the entries contributing weights, we can use sum(i for i in x if not math.isnan(i)).
then for when only the existence of the digit matters, you can use sum(1 for i in x if not math.nan(i)) as above.
Exercise 41:
Compute the sum of diagonal elements in a 2D list.
soln
import random
random.seed(3)
n = 10
my_list = [ [random.randint(0,n) for _ in range(n) ] for _ in range(n)]
diag_2d = lambda l: sum(l[i][i] for i in range(n))
print(my_list)
print(diag_2d(my_list))
Exercise 42:
Convert radians to degrees for each element in a list.
soln
import math
convert_list = [1, 2, 0.5, 0.25]
rad_2_deg = lambda x: [y*180/math.pi for y in x]
#rad_2_deg = lambda x: list(map(lambda y: y*180/math.pi, x))
print(rad_2_deg(convert_list))
Exercise 43:
Calculate the pairwise Euclidean distance between two lists.
soln
import math
first_list = [1, 2, 0.5, 0.25]
second_list = list(range(4))
pairwise_euc = lambda x, y: [abs(i[0] - i[1]) for i in zip(x,y)]
print(pairwise_euc(first_list, second_list))
Exercise 44:
Create a list and set the values between the 25th and 75th percentile to 0.
soln
def percentile(data, percentile):
data = sorted(data)
k = (len(data) - 1) * (percentile / 100)
return data[int(k)]
lst = [10, 20, 30, 40, 50]
q1 = percentile(lst, 25)
q3 = percentile(lst, 75)
lst = [0 if q1 <= x <= q3 else x for x in lst]
print(lst)
lst = [10, 20, 30, 40, 50]
percentile_25th = sorted(lst)[int(len(lst) * 0.25)] # indexing into the first quarter
percentile_75th = sorted(lst)[int(len(lst) * 0.75)]
lst = [0 if percentile_25th <= x <= percentile_75th else x for x in lst]
print(lst)
Exercise 45:
Calculate the element-wise square of the difference between two lists.
soln
import math
first_list = [1, 2, 0.5, 0.25]
second_list = list(range(4))
pairwise_squared = lambda x, y: [(i[0] - i[1])**2 for i in zip(x,y)]
print(pairwise_euc(first_list, second_list))
Exercise 46:
Replace all even numbers in a list with the next odd number.
soln
my_list = list(range(10))
replace_evens = lambda l: list(map(lambda y: y+1 if y%2==0 else y, l))
print(replace_evens(my_list))
Exercise 47:
Create a 2D list and normalize each column by its range.
soln (worst code I’ve ever written 🤠
random.seed(4)
twod_list = [list(random.randint(0,10) for _ in range(10)) for _ in range(4)]
get_range_rows = lambda l: sorted(new_list,reverse=True)[0] - sorted(new_list)[0]
normalise_2d_rows = lambda l: [ [l[row_idx][col_idx]/get_range_rows(row) for col_idx in range(len(row))] for row_idx, row in enumerate(l) ]
get_range_cols = lambda matrix: (num_rows := len(matrix),
num_cols := len(matrix[0]),
[max(row[col_idx] for row in matrix) - min(row[col_idx] for row in matrix) for col_idx in range(num_cols)])[-1]
normalise_2d_cols = lambda l: [ [(l[row_idx][col_idx]-min(row[col_idx] for row in l))/(get_range_cols(l))[col_idx] for col_idx in range(len(row))] for row_idx, row in enumerate(l) ]
print(twod_list)
print(get_range_cols(twod_list))
#print(sorted(twod_list,reverse=True))
#print(normalise_2d_rows(twod_list))
print(normalise_2d_cols(twod_list))
soln (official)
import random
matrix = [[random.random() for _ in range(3)] for _ in range(3)]
min_col = [min(row[i] for row in matrix) for i in range(3)]
max_col = [max(row[i] for row in matrix) for i in range(3)]
normalized_matrix = [[(row[i] - min_col[i]) / (max_col[i] - min_col[i]) for i in range(3)] for row in matrix]
print(normalized_matrix)
Exercise 48:
Compute the cumulative sum of elements along a given axis in a 2D list.
soln
cum_sum = lambda l, axis: [ [sum(l[row_idx][:col_idx+1]) for col_idx in range(len(row)) ] for row_idx, row in enumerate(l) ]
print(twod_list)
print(cum_sum(twod_list, 0))
cum_sum_lambda = lambda l, axis: (
[
[sum(col[0:row_idx+1]) for row_idx in range(len(col))]
for col in zip(*l)
] if axis == 0 else [
[sum(row[0:col_idx+1]) for col_idx in range(len(row))]
for row in l
]
)
print(cum_sum_lambda(twod_list, 0))
print(cum_sum_lambda(twod_list, 1))
Exercise 49:
Check if any element in a list is non-zero.
soln
non_zero = lambda l: any(l)
print(non_zero(twod_list[0]))
Exercise 50:
Create a 2D list with random integers and replace all values greater than a certain threshold with that threshold.
soln
threshold_replace = lambda l, t: [ [ t if l[row_idx][col_idx] > t else l[row_idx][col_idx] for col_idx in range(len(row)) ] for row_idx, row in enumerate(l) ]
print(threshold_replace(twod_list, 5))
Exercise 51:
Find the median of a list of numbers.
soln
import random
random.seed()
list_nums = [random.randint(0,5) for _ in range(5)]
median = lambda l: l[len(l) / 2 if len(l) % 2 == 0 else len(l)//2 ]
print(list_nums)
print(median(list_nums))
Exercise 52:
Convert a list of numbers to a list of their logarithms.
soln
import math
log_list = lambda l: [math.log(x) for x in l]
print(log_list(list_nums))
Exercise 53:
Find the mode of a list of numbers.
soln
disclaimer: this implementation does not deal with multiple most often occurring values
list_nums = [random.randint(0,5) for _ in range(5)]
def mode(l):
uniques = set(l)
mo = (0,) # most often
for x in uniques:
y = l.count(x)
if y > mo[0]:
mo = (y, x)
return mo[1]
print(list_nums)
print(mode(list_nums))
Exercise 54:
Flatten a list of lists.
soln
nested_list = [[ [ random.randint(0,4) for _ in range(4) ] for _ in range(3) ] for _ in range(2) ]
twod_nested_list = [ [ random.randint(0,4) for _ in range(4) ] for _ in range(3) ]
print(nested_list)
unwrap_2d = lambda l: [x for rows in l for x in rows]
print(unwrap_2d(twod_nested_list))
print(nested_list)
unwrap_3d = lambda l: [x for matrices in l for rows in matrices for x in rows]
print(unwrap_3d(nested_list))
Exercise 55:
Transpose a 2D list.
soln
print(twod_nested_list)
transpose = lambda l: [[ l[j][i] for j in range(len(l)) ] for i in range(len(l[0]))]
print(transpose(twod_nested_list))
Exercise 56:
Remove duplicates from a list while preserving order.
soln
lst = [5,3,2,3,4,5,5,1,2,1,1]
seen = set()
print(set(lst)) # note that this orders things, that's all.
unique_lst = [x for x in lst if not (x in seen or seen.add(x))] # i'm not grasping the seen.add(x) part.
print(unique_lst)
Exercise 57:
Find the intersection of two lists.
soln
lst1 = [5,2,5,3,1,2]
lst2 = [1,3,9,5,2]
print(set(lst1).intersection(lst2))
# turns out there's another way:
print(set(lst1) & set(lst2))
Exercise 58:
Merge two dictionaries.
soln
dic1 = {'a': 1, 'c': 6}
dic2 = {'d': 6, 'r': 2, 'l': 3}
print(dic1 | dic2)
# furthermore, there is
print({**dic1, **dic2})
Exercise 59:
Sort a list of dictionaries by a key.
soln
print(sorted(dic2.items(), key=lambda x:x[0])) # can sort on values with x[1]
this is actually not what the question asked for. they asked for sorting on a specific key from a list of dicts.
lst = [{'name' : 'Alice', 'age': 10}, {'name':'Bob','age':15}, {'name':'Charlie','age':20}]
print(sorted(lst, key=lambda x:x['age']))
Exercise 60:
Filter a dictionary based on its values.
soln
d = {'a': 1, 'b':2, 'c':3}
filtered_dict = {k:v for k,v in d.items() if v > 1}
print(filtered_dict)
Exercise 61:
Create a dictionary from two lists.
soln
keys = ['a','b','c','d']
values = [1,2,3,4]
joined_dict = dict(zip(keys,values))
print(joined_dict)
Exercise 62:
Find the maximum value in a dictionary.
soln
print(max(joined_dict))
print(max(joined_dict.items()))
print(max(joined_dict.values()))
Exercise 63:
Invert a dictionary (swap keys and values).
soln
new_dict = {v:k for k,v in joined_dict.items()}
print(new_dict)
Exercise 64:
Create a dictionary with a default value.
soln
keys = ['x', 'y', 'z']
v = 5
mydict = {k:v for k in keys}
print(mydict)
Exercise 65:
Convert a dictionary to a list of tuples.
soln
ts = [item for item in mydict.items()]
# the above is probably a little slower than:
ts_fast = list(mydict.items()) # note that [] is different here than to list.
print(ts_fast)
list comparison aside
# [] is different to list(). [] is a literal, whereas list() is a constructor
# [] is bytecode, list() requires a function call
import timeit
print(timeit.timeit("[]", number=10**6)) # faster
print(timeit.timeit("list()", number=10**6)) # slower
# list() is more versatile and can convert iterables into lists
# [] can only define new lists.
Exercise 66:
Find the length of the longest string in a list.
soln
strings = ["my", "cartridge", "got", "hitroadige", "by", "a", "truck"]
print(max(strings)) # alphabetised
print(max(strings, key=lambda x: len(x)))
Exercise 67:
Reverse the words in a sentence.
soln
s = "oh my god, I might fail this course"
list_of_words = s.split()
print(' '.join(list_of_words[::-1]))
Exercise 68:
Check if a string is a palindrome.
soln
palindrome_checker = lambda s: True if s==s[::-1] else False
print(palindrome_checker("lick"))
print(palindrome_checker("kayak"))
Exercise 69:
Remove punctuation from a string.
soln
import string
remove_punc = lambda s: s.translate(str.maketrans('','',string.punctuation))
print(remove_punc("remove, punc? punk!"))
Exercise 70:
Count the occurrences of each character in a string.
soln
print(s)
count_chars = lambda s: {char: s.count(char) for char in set(s)}
print(sorted(list(count_chars(s).items()), key=lambda x:x[1]))
Exercise 71:
Find the longest common prefix among a list of strings.
soln
lstrings = ["hello", "world", "worldly", "hells"]
def longest_prefix(lstr):
if not lstr:
return ""
shortest_str = min(lstr, key=len)
longest_common_prefix = ""
for i in range(len(shortest_str)):
current_char = shortest_str[i]
if all(x[i] == current_char for x in lstr):
longest_common_prefix += current_char
else:
break
return longest_common_prefix
print(longest_prefix(["flower","flow","flight"]))
Exercise 72:
Convert a string to a list of characters.
soln
stringcheese = "stringcheese"
listcheese = [stringcheese[i] for i in range(len(stringcheese))]
print(listcheese)
# this could be done more easily with:
print(list(stringcheese)) # recall that list takes an iterable object
Exercise 73:
Generate a list of random integers.
soln
import random
rand_list = [random.randint(0,5) for _ in range(5)]
print(rand_list)
Exercise 74:
Shuffle a list.
soln
print(random.shuffle(rand_list)) # returns none
print(rand_list)
Exercise 75:
Generate a random password of a given length.
soln
#cheating with this one to see what the sols want:
import string
import random
length = 8
password = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))
print(password)
Exercise 76:
Calculate the factorial of a number.
soln
def factorial(n):
if n < 0:
return -1
if n == 0:
return 1
return n*factorial(n-1)
print(factorial(-1))
print(factorial(10))
Exercise 77:
Calculate the Fibonacci sequence up to a given number of terms.
soln
def fibonacci(n):
if n == 0:
return 0
if n == 1:
return 1
return fibonacci(n-1) + fibonacci(n-2)
for i in range(10):
print(fibonacci(i))
Exercise 78:
Check if a number is prime.
soln
def is_prime(n):
if n <= 1:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
for i in range(1,20):
print(i, "prime" if is_prime(i) else "not")
Exercise 79:
Find the greatest common divisor (GCD) of two numbers.
soln
def gcd(a, b):
limit = max(a,b)
highest = 1
for i in range(1,limit+1):
if a%i==0 and b%i==0:
highest=i
return highest
print(gcd(8,6))
Exercise 80:
Find the least common multiple (LCM) of two numbers.
soln
""" returns the highest number that is divisible by both a and b """
def lcm(a, b):
i = 1
while True:
if i%a==0 and i%b==0:
return i
else:
i += 1
print(lcm(8,6))
Exercise 81:
Sort a list of tuples by the second element.
soln
lt = [('a',2),('c',3),('b',1)]
sorted(lt,key=lambda x:x[1])
Exercise 82:
Find the second largest number in a list.
soln
second_largest = [5,1,2,1,3,4,7]
sorted(second_largest)[-2]
Exercise 83:
Check if a list is a palindrome.
soln
p = ['k', 'a', 'y', 'a', 'k']
n = ['n', 'o', 't']
def list_palindrome(l):
for i in range(len(l)//2):
if l[i] != l[-1-i]:
return False
return True
list_palindrome(n)
Exercise 84:
Find the sum of the digits of a number.
soln
num = 804
def sum_digits(n):
digits = len(str(n))
sum = 0
for i in range(digits):
sum += int(str(n)[i])
return sum
sum_digits(num)
Exercise 85:
Find the product of the digits of a number.
soln
def prod_digits(n):
digits = len(str(n))
prod = 1
for i in range(digits):
prod *= int(str(n)[i])
return prod
prod_digits(43)
Exercise 86:
Check if a string is a valid number.
soln
def check_str_is_num(s):
return s.replace('.', '', 1).isdigit()
check_str_is_num("6s")
check_str_is_num("s")
check_str_is_num("7")
check_str_is_num("4.0")
Exercise 87:
Find the length of the longest word in a sentence.
soln
import string
sentence = "here are some words in a sentence"
def len_longest_word(s):
words = s.split()
return len(max(words, key=len))
#return ' '.join(["word", "maybe", "cat"])
len_longest_word(sentence)
Exercise 88:
Convert a list of tuples to a dictionary.
soln
print(lt)
print(dict(lt))
Exercise 89:
Filter a list of dictionaries based on a key value.
soln
lst = [{'name': 'Vivek', 'age': 25}, {'name': 'Esther', 'age': 22}, {'name': ' Neassa', 'age': 28}]
filtered_lst = [x for x in lst if x['age'] > 23]
print(filtered_lst)
Exercise 90:
Sort a list of tuples by multiple keys.
soln
one thing to understand is that tuples can be n-dimensional: (a,b,c,d,...,n)!
list_of_t = [(1,2,3,4),(1,2,3),(4,2,1),(1,2,3)]
print(sorted(list_of_t,key=lambda x: (x[1],x[2])))
note also that you can get an IndexError if the lambda func within sorted is accessing outofbounds incdices.
[(4, 2, 1), (1, 2, 3, 4), (1, 2, 3), (1, 2, 3)]
Exercise 91:
Merge two lists into a dictionary, using one as keys and the other as values.
soln
keys = ['jonah','sarah','cupcake']
values = [14,21,33]
merge_lists_dict = lambda k,v: dict(zip(k,v))
print(merge_lists_dict(keys,values))
Exercise 92:
Create a dictionary with keys as numbers and values as their squares.
soln
nums = range(6)
dict_square = dict(zip(nums, [x**2 for x in nums]))
print(dict_square)
Exercise 93:
Check if two strings are anagrams.
soln
I may have glimpsed at the solution, it’s quite clean
str1, str2 = "listen", "silent"
str3, str4 = "mold", "wolf"
check_anagram = lambda s1,s2: True if sorted(s1)==sorted(s2) else False
print(check_anagram(str1,str2))
print(check_anagram(str3,str4))
Exercise 94:
Count the number of vowels in a string.
soln
vowel_counter= lambda s: sum(1 for c in s.lower() if c in "aeiou")
print(vowel_counter("hello world's people"))
Exercise 95:
Check if a string contains only digits.
soln
str_is_dig = lambda s:True if sum(1 for c in s if c.isdigit()) == len(s) else False
print(str_is_dig("123"))
print(str_is_dig("12a"))
# as it turns out, you don't even need the for loop:
print("123456".isdigit())
print("1a23".isdigit())
Exercise 96:
Find the first non-repeated character in a string.
soln
this one is pretty interesting. I’ve never used the next iterator:
ultimate = "frisbee"
non_repeated_char = lambda s: [char for char in s if s.count(char) == 1][0] # you could also use next!
print(non_repeated_char(ultimate))
print(non_repeated_char(ultimate))
Exercise 97:
Reverse each word in a sentence.
soln
s = "oh my god, I will not fail any course"
s_as_l = s.split()
print(' '.join(word[::-1] for word in s_as_l))
Exercise 98:
Generate a list of Fibonacci numbers up to a given number.
soln
def fibonacci(n):
if n == 0:
return 0
if n == 1:
return 1
return fibonacci(n-1) + fibonacci(n-2)
def fibo_until(x):
n=0
y=[fibonacci(n)]
while x >= y[n]:
fib = fibonacci(n)
if fib > x:
break
n+=1
y.append(fib)
return y
print(fibo_until(55))
Exercise 99:
Remove all whitespaces from a string.
soln
tring = "here are some words and a \n"
print(tring.strip()) # won't replace all whitespace, only trailing and leading.
print(tring.replace(" ", ""))
Exercise 100:
Replace all occurrences of a substring in a string.
soln
mainstr = "my mother is a grand wolf"
print(mainstr.replace("wolf", "bob"))
instructGPT appendix
def binomial_coefficient(n, r):
C = [0 for i in range(r+1)]
C[0]=1
for i in range(1,n+1):
j = min(i,r)
while j > 0:
C[j] += C[j-1]
j -= 1
print(C)
return C[r]
binomial_coefficient(4,4)
Backlinks (1)
1. Python /wiki/ccs/programming/languages/python/
Data Types
| category | types |
|---|---|
| text | str |
| numeric | int, float, complex |
| sequence | list, tuple, range |
| mapping | dict |
| set | set, frozenset |
| boolean | bool |
| binary | bytes, bytearray, memoryview |
| none | NoneType |
Time Complexities 1
lists
| operation | time complexity |
|---|---|
sequence.append(item) | \(\mathcal{O}(1)\) |
sequence.pop(item) | \(\mathcal{O}(1)\) |
sequence.insert(0,item) | \(\mathcal{O}(n)\) |
sequence.pop(item,0) {{< mnote “slow because popping at start requires shifting all indices down” >}} | \(\mathcal{O}(n)\) |
sequence[index] | \(\mathcal{O}(1)\) |
sequence[index]=value | \(\mathcal{O}(1)\) |
item in sequence | \(\mathcal{O}(n)\) |
len(sequence) | \(\mathcal{O}(1)\) |
sequence.extend(iterable) | \(\mathcal{O}(k)\) |
sequence + other_sequence | \(\mathcal{O}(n+k)\) |
sequence[index:index+k] | \(\mathcal{O}(k)\) |
sequence.index(item) | \(\mathcal{O}(n)\) |
sequence.count(item) | \(\mathcal{O}(n)\) |
for item in sequence: | \(\mathcal{O}(n)\) |
double-ended queue (deque)
| operation | description | time complexity |
|---|---|---|
queue.append(item) | Add item to right end | \(\mathcal{O}(1)\) |
queue.appendleft(item) | Add item to left end | \(\mathcal{O}(1)\) |
queue.pop() | Remove and return item from right end | \(\mathcal{O}(1)\) |
queue.popleft() | Remove and return item from left end | \(\mathcal{O}(1)\) |
queue.extend(iterable) | Add all elements from iterable to right end | \(\mathcal{O}(k)\) |
queue.extendleft(iterable) | Add all elements from iterable to left (reversed) | \(\mathcal{O}(k)\) |
queue.remove(value) | Remove first occurrence of value | \(\mathcal{O}(n)\) |
queue.rotate(n) | Rotate n steps right (negative for left) | \(\mathcal{O}(k)\) |
queue.clear() | Remove all elements | \(\mathcal{O}(n)\) |
queue.count(value) | Count occurrences of value | \(\mathcal{O}(n)\) |
queue.index(value) | Find index of first occurrence of value | \(\mathcal{O}(n)\) |
queue.reverse() | Reverse elements in place | \(\mathcal{O}(n)\) |
item in queue | Check if item exists in queue | \(\mathcal{O}(n)\) |
queue[0] or queue[-1] | Access first or last element | \(\mathcal{O}(1)\) |
queue[i] | Access element at index i | \(\mathcal{O}(n)\) |
for item in queue | Iterate through all elements | \(\mathcal{O}(n)\) |
dictionary
| operation | time complexity |
|---|---|
mapping[key]=value | \(\mathcal{O}(1)\) |
mapping[key] | \(\mathcal{O}(1)\) |
mapping.get(key) | \(\mathcal{O}(1)\) |
mapping.pop(key) | \(\mathcal{O}(1)\) |
key in mapping | \(\mathcal{O}(1)\) |
for k, v in mapping.items() | \(\mathcal{O}(n)\) |
next(iter(mapping)) | \(\mathcal{O}(1)\) |
next(reversed(mapping)) | \(\mathcal{O}(1)\) |
value in mapping.values() | \(\mathcal{O}(n)\) |
mapping.update(iterable) | \(\mathcal{O}(k)\) |
set
| operation | time complexity |
|---|---|
my_set.add(item) | \(\mathcal{O}(1)\) |
my_set.remove(item) | \(\mathcal{O}(1)\) |
item in my_set | \(\mathcal{O}(1)\) |
for item in my_set | \(\mathcal{O}(n)\) |
set1 & set2 | \(\mathcal{O}(n)\) |
set1 | set2 | \(\mathcal{O}(n)\) |
set1 ^ set2 | \(\mathcal{O}(n)\) |
set1 - set2 | \(\mathcal{O}(n)\) |
counter
| operation | time complexity |
|---|---|
counter[item] | \(\mathcal{O}(1)\) |
counter.pop(item) | \(\mathcal{O}(1)\) |
for k, v in counter.items(): | \(\mathcal{O}(n)\) |
for k, v in counter.most_common(): | \(\mathcal{O}(n\log(n))\) |
for k, v in counter.most_common(k): | \(\mathcal{O}(n \log(k))\) |
counter.update(iterable) | \(\mathcal{O}(k)\) |
counter.subtract(iterable) | \(\mathcal{O}(k)\) |
counter.total() | \(\mathcal{O}(n)\) |
heap / priority queue
| operation | time complexity |
|---|---|
heapq.heapify(sequence) | \(\mathcal{O}(n)\) |
heapq.heappop(sequence) | \(\mathcal{O}(\log(n))\) |
heapq.heappush(sequence, item) | \(\mathcal{O}(\log(n))\) |
sequence[0] | \(\mathcal{O}(1)\) |
sorted list
| operation | time complexity |
|---|---|
sorted_sequence = sorted(sequence) | \(\mathcal{O}(n\log(n))\) |
sorted_sequence.index(item) | \(\mathcal{O}(n)\) |
bisect.bisect(sorted_sequence, item) | \(\mathcal{O}(\log(n))\) |
bisect.insort(sorted_sequence, item) | \(\mathcal{O}(n)\) |
general traversals:
| operation | time complexity |
|---|---|
min(iterable) | \(\mathcal{O}(n)\) |
max(iterable) | \(\mathcal{O}(n)\) |
sorted(iterable) | \(\mathcal{O}(n\log(n))\) |
heapq.nsmallest(k, iterable) | \(\mathcal{O}(n\log(k))\) |
statistics.multimode(iterable) | \(\mathcal{O}(n)\) |
information courtesy of https://www.pythonmorsels.com/time-complexities/ ↩︎