0% found this document useful (0 votes)
5 views12 pages

Topic 2 Lists and Loops

The document covers Python programming concepts related to functions, parameters, loops, and lists, aimed at economics students. It emphasizes the importance of understanding function arguments, the structure and manipulation of lists, and the use of loops for code flow control. Practical examples and coding tips are provided to enhance learning and troubleshooting in Python programming.

Uploaded by

James SI
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views12 pages

Topic 2 Lists and Loops

The document covers Python programming concepts related to functions, parameters, loops, and lists, aimed at economics students. It emphasizes the importance of understanding function arguments, the structure and manipulation of lists, and the use of loops for code flow control. Practical examples and coding tips are provided to enhance learning and troubleshooting in Python programming.

Uploaded by

James SI
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

Topic 2: Lists and Loops

Python Programming for Economics


Dr. Marcus Roel
Spring 2024, UNNC

Today
Functions: parameter and arguments
More code flow: loops (while, for)
lists, and list like objects
QOL Notes
When you write new code, and it doesn't work ...
start from the fewest lines of code possible (then expand after)
start with the smallest changes possible from code that works
typos, etc., are all a thing and hard to spot!
(Increase the size of your fonts)
work slowly
If you're using jupyter notebooks and things don't work
Restart the Python Code in the background by:
Menu > Kernel > Interrupt Kernel
And then run your code-cell again
If all fails, restart notebook completely (sad but true)
If jupyter acts like a complete mess on your system check with friend/me to see if
your code is wrong (most of the time it is) or whether something stranger is
happening (1/100 cases)
Try another coding environment (Pycharm, Visual Studio, etc.) if nothing works
IT Service Desk Plus (Wednesday/Thursdays, 14-16:00 at Info Desk 1F Library,
Info Desk )

Parameters and Arguments


In [4]: def example_arg_order(x, y):
# f'strings. Variable inside {} points to variable, rest is text.
print(f"First argument = {x}, second argument = {y}")

example_arg_order("a", "b")

First argument = a, second argument = b

In [5]: y = "a"
x = "b"

example_arg_order(y, x)

First argument = a, second argument = b

Var y is passed in as first argument, x as second


Parameters y, x of the function have nothing to do with the variables x, y outside
What does example_arg_order(y="b", x="a") do ?
In [ ]: # Note, the repetition of "What does..." is intentional here for slides.

What does example_arg_order(y="b", x="a") do ?


In [6]: example_arg_order(y="b", x="a")

First argument = a, second argument = b

Positional and Keyword Params & Args


Parameters are defined by the names (doc: "named entities") in a function def
x, y are the parameters in def example_arg_order(x, y):
Argument: a value passed to a function when calling the function
"a", "b" are arguments when calling func example_arg_order("a", "b")`
Careful: most sources online tend to use parameters and arguments interchangably
By default, a parameter is a positional-or-keyword parameter
it can be called via it's position in the definition or (possibly) out of order by
parameter_name = value
Rule: When calling a function, all positional arguments must be passed before
keyword arguments
True even if we preserve the order of the parameters
Possible to force position only, keyword only, etc.
details: https://docs.python.org/3/glossary.html#term-parameter )
again, careful if you read second hand material: often not quite right
In [7]: # This works:
example_arg_order("b", y="a")

First argument = b, second argument = a

In [8]: # This does not


example_arg_order(x="a", "b")

Cell In[8], line 2


example_arg_order(x="a", "b")
^
SyntaxError: positional argument follows keyword argument

It's a hard rule. Not clear why this shouldn't work : |


In [9]: # This also does not:
example_arg_order("b", x="a")

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[9], line 2
1 # This also does not:
----> 2 example_arg_order("b", x="a")

TypeError: example_arg_order() got multiple values for argument 'x'

Intuition: both "b" and "a" could be meant for parameter x


Think python starts from the "left" when assigning arguments to parameter

Default Values
An parameter in a function can have a predetermined value
Example: func(x, y, z=10)
Rule: parameters with default values (default argument) must follow non-default
argument (similar to argument/keyword argument rule)
Beautiful in two ways:
implement a standard-case automatically while building in flexibility
function call can skip arguments with default values
In [ ]: # This works:
def func_(x, y=5):
pass # pass is the empty function keyword.

In [ ]: # This does not work:


def func_(x=5, y):
pass

In [28]: def default_arguments(a, b, y=10, z=5):


print(f"a={a}, b={b}, y={y}, z={z}")
In [29]: default_arguments(1, 2, 3, 4)

a=1, b=2, y=3, z=4

In [30]: # Can skip last two arguments


default_arguments(1, 2)

a=1, b=2, y=10, z=5

In [32]: # Can skip just the last


default_arguments(1, 2, 3)

a=1, b=2, y=3, z=5

In [33]: # Or any of the last actually.


default_arguments(1, 2, z=4)

a=1, b=2, y=10, z=4

Code Flow
Real Life Algorithm: Washing dishes
(imagine a world without waimai)
you cooked and ate with a friend, and now you have to wash the dishes
there are
4 chopsticks
6 bowls
2 plates
1 pan
2 glasses
1 pot
write an algorithm to clean those dishes (that you can give to your friend to do it)
A not very good algo
Take one chopstick, wash it, put it on the drying rack
Take one chopstick, wash it, put it on the drying rack
Take one chopstick, wash it, put it on the drying rack
Take one chopstick, wash it, put it on the drying rack
Take one bowl, wash it, put it on the drying rack
[...]
A slightly better algo
Check if there is a dirty kitchen item, take it, wash it, put it on the drying rack
Check if there is a dirty kitchen item, take it, wash it, put it on the drying rack
...
Check if there is a dirty kitchen item, take it, wash it, put it on the drying rack
A much better algo
[1.] Check if there is a dirty kitchen item
[1.1] if there is, take it, wash it, put it on the drying rack. Go back to [1.]
[1.2] if there is not. You are done : )

while Loop
while condition-is-true:
some code

a loop that keeps on repeating the code within as long as its condition is met
while loops are useful when the number of iterations needed is unknown at the
start (and depends on outcome of loop contents), e.g., dirty dish still exists
Two things are crucial when using a while loop:
in order to run (once), the logical expression should evaluate to true when loop
begins
you must update that condition (at least sometimes) inside the loop
otherwise, your loop runs forever
In [11]: i = 1 # Variables must be set before the while loop
while i<10: # Similar to the if-statement we know
print(f"i = {i}")
i = i + 1
# When reaching the end of the block of code,
# we go back to the beginning of the while-loop

i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9

Some syntax
in loops, we often want to add (subtract, etc.) to a given number, e.g. i = i + 1
simple syntax for this: i += 1, i -= 1, etc.
works for all typical mathematical operations: plus (+), minus (-), multiplication (*)
and division (/), exponentiation (**) and remainder, or modulo (%; e.g., 5 % 3 = 2)
note: you don't need to use these simplifications. they don't make you better
coders; they just help you write less :)
Hangman while loop
num_missed_guesses = 0
while num_missed_guesses < 7:
guess = input("Make a guess.")
main_code_goes_here()

Terminating while-loops
The keyword break can be used in a while loop to immediately terminate
execution.
This practise is of questionable coding quality, however
why? the while loop defines a clear condition for which it executes.
breaking in loop (say if i == 5: break ) introduces yet another condition
this makes it difficult to read code

lists
Lists are a built-in container data type which hold other data
e.g., floats, integers, complex numbers, strings or even other lists.
Basic lists are constructed using square braces, [] , with values are separated
using commas.
Example: a list of numbers (int/float) can be used to express a vector.
my_list = [5, 10, 35, 2]
Probably the most essential tool in Python programming
List properties
List items are ordered
implication: you can access them by their index, i.e., my_list[index]
for a one-dimensional list, the indices are 0, 1, ..., n-1
in coding, most numbered items start at 0!
and mutable (changable)
you can reasign values to a position to the list: my_list[2] = 2
(as well as many other operations, see later)
Example list
In [34]: my_list = [5, 10, 35, 7]
print(f"my_list = {my_list}")

my_list = [5, 10, 35, 7]

In [13]: my_list[2] = 2
print(f"\nSet third list item to 2 yields: {my_list}")

Set third list item to 2 yields: [5, 10, 2, 2]

Lists can contain not just numbers.


In [14]: my_breakfast_items = ['Oats', 'Milk', 'Cashew Nuts']
print(my_breakfast_items)

['Oats', 'Milk', 'Cashew Nuts']

What do we need most from lists?


In typical applications, we use lists to either access its data (done by index),
or to store data during code execution
hangman: store past guesses
(work example) compute average HR of subjects for separate events and then
stored these
store data when webscraping
Adding to lists: single items
list.append(item)

e.g., today, I also ate an apple:


In [15]: my_breakfast_items.append("Apple") # Add item to existing list.
print(f"Today's breakfast was: {my_breakfast_items}")

Today's breakfast was: ['Oats', 'Milk', 'Cashew Nuts', 'Apple']

Adding to lists: other lists


To add a list to a list, just use the intuitive +
list_1 = list_1 + list_2 (or += )
Adding isn't elementwise for list in python, which doesn't make much sense beyond
vectors or matrices
Much more reader friendly than .extend(other_list)
In [16]: my_breakfast_items = my_breakfast_items + ["Coffe", "Croissant"]
print(my_breakfast_items)

['Oats', 'Milk', 'Cashew Nuts', 'Apple', 'Coffe', 'Croissant']


Note: careful 're-executing the above cell multiple times.
You will grow the lists with each time as we add to existing one.
Accessing more than one item: slicing
Instead of accessing a single item, we can also get a slide (part of the list) by
indicating the elements from i to j (not included) that we want to access, e.g.
my_list[i:j]
[:j] gets all items until j
[i:] gets all items from i
[-i:-j] counts from the back instead of the front, i.e., gets the last i to j, (i must
be greater than j)
the non-inclusion of the last item feels strange at first. But it will become intuitive -
especially in view of len(my_list)
In [36]: my_list = [1, 3, 5, 7, 9]

In [37]: print(my_list[2:4])

[5, 7]

In [38]: print(my_list[1:])

[3, 5, 7, 9]

Feel free to try out the remaining yourself : ).


Personally, I don't use slicing notations much at all!
List Functions and Methods (just fyi)
The most common list functions/methods are as follows (you'll learn some as we go
along)
Function Method Description

list.append(x, value ) x.append(value) Appends value to the end of the list.

len(x) − Returns the number of elements in th

list.extend(x, list ) x.extend(list) Appends the values in list to the exist

list.pop(x, index ) x.pop(index) Removes the value in position index a

list.remove(x, value ) x.remove(value) Removes the first occurrence of value

list.index(x, value ) x.index(value) Returns the lowest index where the v

list.count(x, value ) x.count(value) Counts the number of occurrences of

del x[slice] Deletes the elements in slice.


list of lists
a typical application of storing data is via lists of lists, e.g. each data 'point' (better,
data row) is a list of items, e.g., datapoint is [Name, Age, Hobby]
dataset = [['Marcus', 34, 'Running'],['Lars', 37, 'Play
Guitar']]

Economic Examples: A list of lists with [Subject_id, Employment Status, Age,


Education, Job Experience, Job Tenure, ...]
In [35]: x = [[1,2,3,4], [5,6,7,8]]
print(f"x = {x}")

x = [[1, 2, 3, 4], [5, 6, 7, 8]]

Accessing items in lists of lists is intuitive:


list[0] -> first item in highest level list
list[1][3] -> second item in highest level (we start counting at 0), and it's third
item.
In [39]: print(f"x[0] = {x[0]}") # Notice that this returns a list

x[0] = [1, 2, 3, 4]

In [40]: print(f"x[1][3] = {x[1][3]}") # This returns just a value.

x[1][3] = 8

In [41]: dataset = [['Marcus', 34, 'Running'], ['Lars', 37, 'Play Guitar']]


print(dataset[1][2])

Play Guitar

for Loop
for item in sequence:
Code to run

a loop that iterates over a sequence (a list, or related container concepts (later),
general 'iterables', but even strings)
item is an item in the sequence (iterable), and can be accessed in the codeblock!
the loop will go over all items in the sequence
when the sequence is multidimensional, it will only go over the highest-level,
equivalent to x[0] , x[1] , etc.
unlike the while loop, it may make sense to terminate loop early with break
continue can be used to skip an iteration of a loop, immediately returning to the
top of the loop using the next item in iterable.
In [43]: my_preferred_breakfast = ['Coffee', 'Cashew Nuts', 'Cookies']
for x in my_preferred_breakfast:
print(x)

Coffee
Cashew Nuts
Cookies

Class Question: Write a for loop checks for cookies (and stops when found) in
my_preferred_breakfast = ['Coffee', 'Cashew Nuts', 'Cookies',
"Orange"]

Solution (click)
Interestingly: text is also iterable
In [45]: for character in "Gingerbread":
print(character)

G
i
n
g
e
r
b
r
e
a
d

for-Loop - Real World Example


I ran multiple experiments, which were stored in the files
oTree_pilot_1, oTree_pilot_2, oTree_pilot_3
I wanted to import these data files, add some (different) information to each file and
then combine them into one large dataset

list_data = [] # combined data


for file in ['oTree_pilot_1.csv', 'oTree_pilot_2.csv',
'oTree_pilot_3.csv']:
df = pandas.read_csv(file)
# pandas is a great data libary we will learn later on! can
load files from folders :)
do_some_stuff_to(df)
list_data.append(df)

turn_list_data_into_single_dataset()

Comment
Be careful when modifying the sequence itself when iterating.
(for now, best avoided) may cause unintended effects (unless you really know what
you are doing)

range()
A range is most commonly encountered in a for loop.
range(start, stop, step) creates a sequence of
with stop not included.
start, start + step, start + 2 ⋅ step, … , stop

range(start, stop) is the same as range(start, stop, 1)


range(stop) is the same as range(0, stop) and most commonly used
can be used to create a list by list(range(start,stop))
In [23]: range_1 = range(3,11)
print(type(range_1))

<class 'range'>

In [24]: list_1 = list(range(3,11))


print(list_1)

[3, 4, 5, 6, 7, 8, 9, 10]

range() to create for loops


In [46]: for num in range(5):
print(num)

0
1
2
3
4

In [26]: # Not a good application; but it's a nice example.


list_num = [5,10,20,40]
for index in range(len(list_num)):
print(f"the item at position = {index} is: {list_num[index]}")
the item at position = 0 is: 5
the item at position = 1 is: 10
the item at position = 2 is: 20
the item at position = 3 is: 40

Why is it not good?


In general, it should be enough to just know the value of the item.
(but there are use-cases for this)

enumerate()
If you really wanted to know the index value, we can use the built-in enumerate
iterates over a list and returns both the index and item; access them as follows:
In [27]: list_num = [5,10,20,40]
for index, item in enumerate(list_num):
print(index, item)

0 5
1 10
2 20
3 40

You might also like