Python Basics
This notebook is part of the SECQUOIA Research Group Pyomo Tutorial. The public self-study build includes solution cells immediately after prompts so learners can compare their work.
Learning objectives¶
By the end of this chapter, you should be able to:
manipulate Python lists, dictionaries, loops, and functions;
use list comprehensions and generators for compact data transformations;
read tabular data with pandas;
prepare Python data structures for Pyomo modeling examples.
1. Lists¶
Lists are mutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application).
Lists are enclosed by brackets ([ ]) and their elements and size can be changed.
In this section, we will replace list elements and use indexes to access items in a sequence.
s[i] returns the item at index i.
The list is given as follows:
a = [1, 2, 3, 4, 5]Exercise 1.1¶
Replace the ‘1’ in the list with the string ‘foo’.
# Write your answer here.
a = [1, 2, 3, 4, 5]
a[0] = "foo"
print("CHECK a is:", a) # check your work
CHECK a is: ['foo', 2, 3, 4, 5]
Exercise 1.2¶
Replace the 4 in the list a with the string bar.
# Write your answer here.
a = [1, 2, 3, 4, 5]
a[3] = "bar"
print("CHECK a is:", a) # check your work
CHECK a is: [1, 2, 3, 'bar', 5]
In Python, all sequences, be they lists, strings, or tuples, support indexing, which allows for the direct access of individual items within the sequence.
The numbering of these indices starts from zero (0); hence, the initial item in any sequence is found at the zeroth index.
This implies that for a sequence of n elements, the last item would be positioned at an index of n-1.
Exercise 1.3¶
Given the list a, guess what the output of print(a[-1]) will print.
# Write your answer here.
print(5)
print("CHECK a[-1] is:", a[-1]) # check your work (don't just write this for your answer!)
5
CHECK a[-1] is: 5
Another unique feature of sequence indexing in Python is the support for negative indices, which provide a means to count from the end of the sequence towards the beginning.
Utilizing this approach, the last item of any given sequence can be accessed using an index of -1.
Progressively, moving further towards the start of the sequence, the indices decrease, meaning the penultimate item would be at index -2, and so forth.
Remarkably, the first item in a sequence can also be accessed using negative indexing by specifying the negative of the sequence’s length, denoted as -length.
Exercise 1.4¶
Given the list a, modify a so that the output is [1, 2, "hello", "world", 4, 5].
# Write your answer here.
a = [1, 2, 3, 4, 5]
a[2:3] = ["hello", "world"]
print("CHECK a is:", a) # check your work
CHECK a is: [1, 2, 'hello', 'world', 4, 5]
In Python, slicing allows you to access a subset or a range of elements from a sequence-like object such as a list, string, or tuple.
This can be accomplished by specifying two indices in the format s[i:j], where s is the sequence.
This expression denotes a slice starting at index i and ending just before index j.
Exercise 1.5¶
After setting list b, what do you expect print(a[2]) to output?
b = a
b[2] = "small"
# Write what you expect print(a[2]) to print.b = a
b[2] = "small"
print("small")
print("CHECK a[2] is:", a[2]) # check your work (don't just write this for your answer!)
small
CHECK a[2] is: small
In Python, using the assignment operator as in b = a for lists doesn’t create a new copy.
Instead, a and b point to the same list in memory.
Therefore, changes made using one variable (like b[2] = "small") also appear when accessed through the other (a), demonstrating Python’s handling of object references.
List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.
Exercise 1.6¶
c is given as a list comprehension. Find what you think print(c[3]) will output.
c = [x for x in range(2, 10)] # this is a list comprehension!# Write your answer here.
c = [x for x in range(2, 10)] # this is a list comprehension!
print(5)
print("CHECK c[3] is:", c[3]) # check your work (don't just write this for your answer!)
5
CHECK c[3] is: 5
A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses.
The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it.
Exercise 1.7¶
Using list comprehensions in Python, write code that transforms the given list d = [6, 5, 4, 3, 2] into [7, 6, 5, 4, 3] by adding 1 to each element.
# Write your answer here.
d = [6, 5, 4, 3, 2]
d = [x+1 for x in d]
print(d)
[7, 6, 5, 4, 3]
2. Dictionaries¶
A dictionary in Python is a mutable and dynamic data structure that maps unique keys to corresponding values, akin to a table. Keys, which are immutable, can be integers, strings, floats, tuples, booleans, or the NoneType, but not mutable types like lists or dictionaries. Values, however, can be any Python object, mutable or immutable. This structure makes dictionaries a versatile tool in Python for storing and manipulating diverse data types in an intuitive key-value format.
We will conduct some exercise problems with the following dictionary
d = {"tree": "wood", "flower": "petal", "earth": "water", 101: [4, 6, 8]}d = {"tree": "wood", "flower": "petal", "earth": "water", 101: [4, 6, 8]}In Python, dictionaries are mutable, which means we can change their content without changing their identity.
Exercise 2.1¶
Given the dictionary d, change the value of the key tree into leaves.
# Write your answer here.
d["tree"] = "leaves"
In Python, dictionaries are not fixed in size. This means that new key-value pairs can be added to the dictionary at any time.
Exercise 2.2¶
Given the dictionary d, add a new key-value pair monty: python to the dictionary.
# Write your answer here.
d["monty"] = "python"
d[key] returns the value for key in the dictionary. If key is not available, then a KeyError will be raised.
Exercise 2.3¶
Given the dictionary d, what do you think print(d["earth"]) will output?
# Write your answer here.
if "earth" in d:
print("The value of 'earth' is:", d["earth"])
else:
print("'earth' is not found in the dictionary.")
The value of 'earth' is: water
Exercise 2.4¶
Print all the pairs in the dictionary d.
# Write your answer here.
print("All key-value pairs:")
print(list(d.items()))
All key-value pairs:
[('tree', 'leaves'), ('flower', 'petal'), ('earth', 'water'), (101, [4, 6, 8]), ('monty', 'python')]
3. Functions¶
A function in Python is a reusable block of code designed to perform a specific task. They play a pivotal role in structuring programs by enabling a divide-and-conquer approach, where a large task is broken down into several smaller, more manageable tasks.
When a function is defined, its code isn’t executed immediately. Instead, the function’s code is run whenever the function is called.
This call can come from various control structures within the program, including sequential code flow and within conditional (like if statements) or repetition structures (like for and while loops).
By encapsulating specific tasks in functions, we can create more organized, readable, and efficient programs.
There are several Exercise Problems for you to practice.
Exercise 3.1¶
Write a function that takes in a list of numbers and prints the value of the largest number. Be sure to test your function. Start with the following code:
def print_max_value(nums):
# Write your answer here.def print_max_value(nums):
print("The max value is: ")
print(max(nums))
test = [1, 2, 3, 4, 5]
print_max_value(test)The max value is:
5
Exercise 3.2¶
Write a function that takes a list of numbers and returns the largest number. Start with the following code:
def max_value(nums):
# Write your answer here.def max_value(nums):
return max(nums)
test = [1, 2, 3, 4, 5]
print(max_value(test))5
Exercise 3.3¶
Do so without using any built-in functions. Start with the following code:
def my_max_value(nums):
# Write your answer here.def my_max_value(nums):
tmp = nums[0]
for i in range(1, len(nums)):
if nums[i] > tmp:
tmp = nums[i]
return tmp
test = [1, 2, 3, 4, 5]
print(my_max_value(test))5
Exercise 3.4¶
Call both functions on a couple different lists of numbers to verify they return the same value.
l1 = [1, 3, 0, 5, -2]
ans1 = max_value(l1)
print(ans1)
ans2 = my_max_value(l1)
print(ans2)
l2 = [12, 0, 11.9]
print(max_value(l2))
print(my_max_value(l2))The max value of l1 is 5, and the max value of l2 is 12.
max_value() and my_max_value() returned the same values for both lists.
l1 = [1, 3, 0, 5, -2]
ans1 = max_value(l1)
print('Max value using the built-in functions :', ans1)
ans2 = my_max_value(l1)
print('Max value without using the built-in functions :', ans2)
l2 = [12, 0, 11.9]
print('Max value using the built-in functions :', max_value(l2))
print('Max value without using the built-in functions :', my_max_value(l2))Max value using the built-in functions : 5
Max value without using the built-in functions : 5
Max value using the built-in functions : 12
Max value without using the built-in functions : 12
Exercise 3.5¶
Write a function that takes a list of numbers and returns a dict consisting of the smallest and largest number (use keys ‘smallest’ and ‘largest’). Be sure to test your function. Start with the following code:
def max_and_min(nums):
# Write your answer here.def max_and_min(nums):
return {'smallest': min(nums), 'largest': max(nums)}
test = [1, 2, 3, 4, 5]
print(max_and_min(test)){'smallest': 1, 'largest': 5}
Exercise 3.6¶
Write a function that takes in two lists and prints any common elements between them hint: check if an item is in a list using: if item in list
def get_common(l1, l2):
# Write your answer here.def get_common(l1, l2):
for i in l1:
if i in l2:
print(i)
get_common(l1, l2)0
4. For Loops¶
A for loop in Python is a control flow structure that allows for a fixed number of iterations, determined by the size of the iterable it traverses. An iterable, in this context, is any object capable of returning its elements one at a time, examples of which include strings, lists, and ranges, among others. With each iteration of the for loop, the variable (often referred to as the loop variable or item) is set to a different value from the iterable. This process continues until all values in the iterable have been assigned to the variable, marking the completion of the loop’s iterations. There are several Exercise Problems for you to practice.
Exercise 4.1¶
Write a for loop that prints the entries of the following list, one at a time:
words = ["Wow,", "python", "is", "really", "cool."]
# Write your answer here.words = ["Wow,", "python", "is", "really", "cool."]
for i in words:
print(i)
Wow,
python
is
really
cool.
Exercise 4.2¶
Write a for loop that computes 2^n only using multiplication by 2.
n = 5
# Write your answer here.n = 5
val = 2
for i in range(0,n-1):
val = val*2
print(val)
32
Exercise 4.3¶
Write a for loop that adds 1 to elements in a list and prints their squared value.
nums = [0, 3, -2, -1]
# Write your answer here.nums = [0, 3, -2, -1]
for i in nums:
print((i+1)**2)
1
16
1
0
5. Pandas¶
Exercise 5.1¶
A colleague wants to build a classifier for sample observations, but is having trouble importing data for the project. Luckily, you know about pandas, the Python data manipulation package.
The file bears-are-bears.csv contains a small human-generated classification data set. Import the file and display it to verify that it matches your expectations.
import pandas as pd
# Write code to import the CSV file and display the DataFrame.
df = pd.read_csv('bears-are-bears.csv', index_col=0)
print(df) Bear Type Weight (kg) Color Endangered Bear Necessities \
Tag #
1 Black bear 280 Black You Charmin Ultra
2 Brown bear 700 Brown No NaN
3 Polar bear 80 White Yes NaN
4 Andean bear 200 Black Vulnerable NaN
5 Panda bear 113 Black and white NaN Bamboo
6 Sloth bear 100 Black Yes NaN
7 Sun bear 50 Black Yes NaN
8 Panda bear 123 Black and white Yes Bamboo
9 Black bear 287 Brown No NaN
10 Black bear 276 Black No NaN
Speed Eats
Tag #
1 Fast Everything
2 NaN Salmon
3 Faster in water Not enough
4 NaN bromeliads
5 NaN Bamboo
6 Slow Insects
7 NaN Insects
8 NaN Bamboo
9 Fast Everything
10 Fast Everything
Exercise 5.2¶
Your colleague wants to have an alphabetically sorted unique list of all the bear types. Generate this from the pandas DataFrame.
# Write code to create and print the sorted unique bear types.
sorted_bears = sorted(df['Bear Type'].unique().tolist())
print("Sorted bears list:")
print(sorted_bears)Sorted bears list:
['Andean bear', 'Black bear', 'Brown bear', 'Panda bear', 'Polar bear', 'Sloth bear', 'Sun bear']
References and credits¶
This notebook adapts material from the public Pyomo Summer Workshop 2018. For Pyomo background, see Hart et al., 2011Bynum et al., 2021.
- Hart, W. E., Watson, J.-P., & Woodruff, D. L. (2011). Pyomo: modeling and solving mathematical programs in Python. Mathematical Programming Computation, 3(3), 219–260.
- Bynum, M. L., Hackebeil, G. A., Hart, W. E., Laird, C. D., Nicholson, B. L., Siirola, J. D., Watson, J.-P., & Woodruff, D. L. (2021). Pyomo–optimization modeling in python (Third, Vol. 67). Springer Science & Business Media.