my_list = [1, 2, 3, [1, 2, 3, [1, 2, 3]]]
my_list[1, 2, 3, [1, 2, 3, [1, 2, 3]]]
FINA 6333 for Spring 2024
A list is a collection of items that are ordered and changeable. You can add, remove, or modify elements in a list. In Python, you can create an empty list using either [] or list().
my_list = [1, 2, 3, [1, 2, 3, [1, 2, 3]]]
my_list[1, 2, 3, [1, 2, 3, [1, 2, 3]]]
Python is zero-indexed!
my_list[0]1
my_list[-1][-1][-1]3
my_list[-1][-1][-1] = 'Matilda'
my_list[1, 2, 3, [1, 2, 3, [1, 2, 'Matilda']]]
my_list[3] is my_list[-1]True
A tuple is similar to a list, but it is immutable, meaning that you cannot change its contents once it has been created. You can create a tuple using parentheses () or the tuple() function.
my_tuple = (1, 2, 3, (1, 2, 3, (1, 2, 3)))
my_tuple(1, 2, 3, (1, 2, 3, (1, 2, 3)))
Tuples are immutable!
# my_tuple[-1][-1][-1] = 'Matilda'
# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# Cell In[14], line 1
# ----> 1 my_tuple[-1][-1][-1] = 'Matilda'
# TypeError: 'tuple' object does not support item assignmentIn the following example, we can replace the innermost 3 with 'Matilda' because it is an object in a list.
my_tuple_2 = (1, 2, 3, (1, 2, 3, [1, 2, 3]))
my_tuple_2(1, 2, 3, (1, 2, 3, [1, 2, 3]))
my_tuple_2[-1][-1][-1] = 'Matilda'A dictionary is a collection of key-value pairs that are unordered and changeable. You can add, remove, or modify elements in a dictionary. In Python, you can create an empty dictionary using either {} or the dict() function.
prices_list = [10, 20, 300] # for AAPL, MSFT, TSLAprices_dict = {'AAPL': 10, 'MSFT': 20, 'TSLA': 300}prices_dict['AAPL']10
my_dict = {'A': 1, 'B': [1, 2, 3], 'C': {'A': 1, 2: 2}}
my_dict{'A': 1, 'B': [1, 2, 3], 'C': {'A': 1, 2: 2}}
A list comprehension is a concise way of creating a new list by iterating over an existing list or other iterable object. It is more time and space-efficient than traditional for loops and offers a cleaner syntax. The basic syntax of a list comprehension is new_list = [expression for item in iterable if condition] where:
expression is the operation to be performed on each element of the iterableitem is the current element being processediterable is the list or other iterable object being iterated overcondition is an optional filter that only accepts items that evaluate to True.For example, we can use the following list comprehension to create a new list of even numbers from 0 to 8: even_numbers = [x for x in range(9) if x % 2 == 0]
List comprehensions are a powerful tool in Python that can help you write more efficient and readable code (i.e., more Pythonic code).
even_numbers = []
for i in range(9):
if i%2 == 0:
even_numbers.append(i)
even_numbers[0, 2, 4, 6, 8]
Here is the cooler, more Pythonic list comprehension version:
[i for i in range(9) if i%2 == 0][0, 2, 4, 6, 8]
a and b using a third variable c.a = 1b = 2c = aa = bb = cdel cprint(f'a: {a}, b: {b}')a: 2, b: 1
a and b without using a third variable c.a = 1b = 2(b, a) = (a, b)print(f'a: {a}, b: {b}')a: 2, b: 1
The parentheses () are optional for tuples, but they are often useful!
_ = 1, 1, 1
type(_)tuple
1, 1, 1 == (1, 1, 1)(1, 1, False)
(1, 1, 1) == 1, 1, 1(False, 1, 1)
Here we can wrap both sides with parentheses to remove ambiguity!
(1, 1, 1) == (1, 1, 1)True
l1 of integers from 1 to 100.l1 = list(range(1, 101))
# the last entry in a code cell prints automatically...
# here I wrap l1 with print for fewer lines of printout
print(l1)[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 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]
l1 to create a list of integers from 60 to 50 (inclusive).Name this list l2.
# with zero-indexing:
# left edge included, right excluded
# so length of list is right - left
l2 = l1[49:60]
l2.reverse()
l2 # most Python methods modify objects "in place"[60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50]
l2_alt = l1[49:60][::-1]
l2_alt[60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50]
l1[-41:-52:-1][60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50]
l3 of odd integers from 1 to 21.l3 = []
for i in range(1, 22):
if i%2 == 1:
l3.append(i)
l3[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
l3_alt = [i for i in range(1, 22) if i%2 == 1]
l3_alt[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
list(range(1, 22, 2))[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
l4 of the squares of integers from 1 to 100.l4 = [i**2 for i in range(1, 101)]
print(l4)[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801, 10000]
l5 that contains the squares of odd integers from 1 to 100.l5 = [i**2 for i in range(1, 101) if i%2 != 0]
print(l5)[1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625, 729, 841, 961, 1089, 1225, 1369, 1521, 1681, 1849, 2025, 2209, 2401, 2601, 2809, 3025, 3249, 3481, 3721, 3969, 4225, 4489, 4761, 5041, 5329, 5625, 5929, 6241, 6561, 6889, 7225, 7569, 7921, 8281, 8649, 9025, 9409, 9801]
strings by the last letter.strings = ['card', 'aaaa', 'foo', 'bar', 'abab']def get_last_letter(x):
return x[-1]get_last_letter(strings[0])'d'
I would usually use the .sort() method, which would modify the strings list in place. However, for this exercise I want to leave the strings list as is, so I can I can repeat this exercise a few times.
sorted(strings)['aaaa', 'abab', 'bar', 'card', 'foo']
sorted(strings, key=get_last_letter)['aaaa', 'abab', 'card', 'foo', 'bar']
Here is the anonymous function version.
sorted(strings, key=lambda x: x[-1])['aaaa', 'abab', 'card', 'foo', 'bar']
Anonymous functions are very Pythonic and the ideal way to implement a calculation that you only plan to use once, thereby avoiding the overhead of writing a function.
nums and an integer k, return the \(k^{th}\) largest element in the array.Note that it is the \(k^{th}\) largest element in the sorted order, not the \(k^{th}\) distinct element.
Example 1:
Input: nums = [3,2,1,5,6,4], k = 2
Output: 5
Example 2:
Input: nums = [3,2,3,1,2,4,5,5,6], k = 4
Output: 4
I saw this question on LeetCode.
def get_largest(x, k):
return sorted(x)[-k]get_largest(x=[3,2,1,5,6,4], k=2)5
get_largest(x=[3,2,3,1,2,4,5,5,6], k=4)4
nums and an integer k, return the k most frequent elements.You may return the answer in any order.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Example 2:
Input: nums = [1], k = 1
Output: [1]
I saw this question on LeetCode.
def get_frequent(nums, k):
counts = {}
for n in nums:
if n in counts:
counts[n] += 1
else:
counts[n] = 1
return [x[0] for x in sorted(counts.items(), key=lambda x: x[1], reverse=True)[:k]]get_frequent(nums=[1,1,1,2,2,3], k=2)[1, 2]
Input: ["aba", "no"]
Output: [True, False]
We can reverse a string with a [::-1] slice just like we reverse a string!
def is_palindrome(xs):
return [x == x[::-1] for x in xs]is_palindrome(["aba", "no"])[True, False]
returns() that accepts lists of prices and dividends and returns a list of returns.prices = [100, 150, 100, 50, 100, 150, 100, 150]
dividends = [1, 1, 1, 1, 2, 2, 2, 2]This type problem is the rare case where I use a loop counter in Python.
def returns(p, d):
rs = []
for i in range(1, len(p)):
r = (p[i] + d[i] - p[i-1]) / p[i-1]
rs.append(r)
return rs%precision 4'%.4f'
returns(p=prices, d=dividends)[0.5100, -0.3267, -0.4900, 1.0400, 0.5200, -0.3200, 0.5200]
Here is a solution that avoids a loop counter and combines a list comprehension zip() to loop over prices, dividends, and lagged prices. This solution may be a little more Pythonic, but I find it harder to follow that our loop-counter solution above.
[(p + d - p_lag) / p_lag for p, d, p_lag in zip(prices[1:], dividends[1:], prices[:-1])][0.5100, -0.3267, -0.4900, 1.0400, 0.5200, -0.3200, 0.5200]
returns() so it returns lists of returns, capital gains yields, and dividend yields.def returns_2(p, d):
rs, d_ps, cg_ps = [], [], []
for i in range(1, len(p)):
r = (p[i] + d[i] - p[i-1]) / p[i-1]
d_p = d[i] / p[i-1]
cg_p = r - d_p
rs.append(r)
d_ps.append(d_p)
cg_ps.append(cg_p)
return {'r': rs, 'd_p': d_ps, 'cg': cg_ps}returns_2(p=prices, d=dividends){'r': [0.5100, -0.3267, -0.4900, 1.0400, 0.5200, -0.3200, 0.5200],
'd_p': [0.0100, 0.0067, 0.0100, 0.0400, 0.0200, 0.0133, 0.0200],
'cg': [0.5000, -0.3333, -0.5000, 1.0000, 0.5000, -0.3333, 0.5000]}
[0, 1].Input: [18.5, 17.0, 18.0, 19.0, 18.0]
Output: [0.75, 0.0, 0.5, 1.0, 0.5]
numbers = [18.5, 17.0, 18.0, 19.0, 18.0]def rescale(x):
x_min = min(x)
x_max = max(x)
# Here is the for-loop equivalent of the list comprehension below
# rescaled = []
# for y in x:
# rescaled.append((y - x_min) / (x_max - x_min))
return [(y - x_min) / (x_max - x_min) for y in x]rescale(numbers)[0.7500, 0.0000, 0.5000, 1.0000, 0.5000]