Advanced Python¶
string formatting (
format
)sets
collections
args & kwargs
list comprehensions
map
overloading operators
…or: a day of shortcuts
Note: Shortcuts make your life easier, but your code less understandable to beginners.
It’s hard to search for things you don’t know exist.
Today’s goal : let you know these things exist.
NOT today’s goal : teach you all the details.
You do not need to incorporate these into your project, but if they’ll help you, go for it!
import antigravity
String Formatting¶
Use the format
method to manipulate and format strings.
name = "Shannon"
job = "Assistant Teaching Professor"
topic = "Python"
"Hello! My name is {}. My job is {}, and I work on {}".format(name, job, topic)
'Hello! My name is Shannon. My job is Assistant Teaching Professor, and I work on Python'
Sets¶
Sets are a variable type that store only unique entries.
my_set = set([1, 1, 2, 3, 4])
my_set
{1, 2, 3, 4}
Like lists, they are iterable & mutable.
my_set.add(6)
my_set
{1, 2, 3, 4, 6}
Clicker Question #1¶
How many values would be in the following set?
clicker_set = set([1, 1, 2, 2, 3, 4])
clicker_set.add(6)
clicker_set.add(1)
clicker_set
{1, 2, 3, 4, 6}
A) 0
B) 4
C) 5
D) 6
E) ¯\_(ツ)_/¯
Reminder that if you add a value that is already in the set…the set will not change
Collections¶
The collections
module has a number of useful variable types, with special properties.
“Special editions” of collections we’ve discussed before (lists, tuples, and dictionaries).
from collections import Counter
# count how many elements there are in collection
# return values in a dictionary
Counter([1, 0, 1, 2, 1])
Counter({1: 3, 0: 1, 2: 1})
import collections
collections.Counter([1, 0, 1, 2, 1])
Counter({1: 3, 0: 1, 2: 1})
# can count how many of each letter are in there
Counter("I wonder how many times I use the letter 'e'")
Counter({'I': 2,
' ': 9,
'w': 2,
'o': 2,
'n': 2,
'd': 1,
'e': 7,
'r': 2,
'h': 2,
'm': 2,
'a': 1,
'y': 1,
't': 4,
'i': 1,
's': 2,
'u': 1,
'l': 1,
"'": 2})
Think back to our encryption scheme!
The most common letter in the English language is ‘e’.
If you just move each letter over by 1 position, you can just use a Counter to crack the code.
Why we moved to a variable encoder!
any
& all
¶
any
and all
evaluate collections for whether elements evaluate as True.
my_bool_list = [True, False, True]
any(my_bool_list)
True
all(my_bool_list)
False
Clicker Question #2¶
What would the following return?
my_list = [True, True, False, True]
any(my_list)
True
A)
True
B)
False
C)
[True, True, True]
D)
[False]
E) ¯\_(ツ)_/¯
getattr
& setattr
¶
getattr
and setattr
can be used to get and set attributes, respectively.
Flexibly return and define instance attributes.
class MyClass():
def __init__(self):
self.var_a = 'string'
self.var_b = 12
# create instance
instance = MyClass()
instance.var_a
# Get a specified attribute
# define var_a as an input
getattr(instance, 'var_a')
# Set a specified attribute
setattr(instance, 'var_b', 13)
print(instance.var_b)
args
& kwargs
¶
allow you to pass a variable number of arguments to a function
*args
- allow any number of extra arguments (including zero)**kwargs
- allow any number of keyword arguments to be passed (as a dictionary)
*args
¶
# use *arguments to demonstrate args
def tell_audience(*arguments):
for arg in arguments:
print(arg)
tell_audience('asdf')
asdf
tell_audience("Hello!",
"My name is Shannon.",
"My job is Assistant Teaching Professor.")
Hello!
My name is Shannon.
Hello!
My job is Assistant Teaching Professor.
**kwargs
¶
def tell_audience_kwargs(**info):
print("type: ", type(info), '\n')
for key, value in info.items():
print("key: ", key)
print("value: ", value, "\n")
tell_audience_kwargs(first='Shannon',
last='Ellis',
email='sellis@ucsd.edu')
type: <class 'dict'>
key: first
value: Shannon
key: last
value: Ellis
List Comprehensions¶
List comprehensions allow you to run loops and conditionals, inside lists.
The general format is :
[ expression for item in list if conditional ]
# NOT a list comprehension
# how we've been doing it
input_list = [0, 1, 2]
output_list = []
for ind in input_list:
output_list.append(ind + 1)
# look at output
output_list
[1, 2, 3]
# This list comprehension is equivalent to the cell above
# note the square brackets on the outside
[ind + 1 for ind in [0, 1, 2]]
[1, 2, 3]
# You can also include conditionals inside a list comprehension
my_list = [1, 2, 3, 4, 5]
my_list2 = [val for val in my_list if val % 2 == 0]
print(my_list)
print(my_list2)
[1, 2, 3, 4, 5]
[2, 4]
Clicker Question #3¶
What would the following return?
list1 = [3, 4, 5]
multiplied = [item * 3 for item in list1]
multiplied
[9, 12, 15]
A)
True
B)
False
C)
[9, 12, 15]
D)
15
E) ¯\_(ツ)_/¯
Note: there are also tuple & dictionary comprehensions.
Regular Expressions¶
Regular expressions allow you to work with specified patterns in strings.
import re
my_string = "If 12 Python programmers try to complete 14 tasks in 16 minutes, why?"
# can just search for a letter
re.findall('o', my_string)
['o', 'o', 'o', 'o']
# but the patterns are where these shine
re.findall('\d\d', my_string)
['12', '14', '16']
filter¶
filter
is a function that takes in another function, and a collection object, and filters the collection with the function.
def is_bool(val):
if isinstance(val, bool):
return True
else:
return False
#filter?
out = []
for val in [1, False, 's', True]:
out.append(is_bool(val))
out
[False, True, False, True]
# apply function to every element of list
# function to apply is first input to filter
list(filter(is_bool, [1, False, 's', True]))
[False, True]
Lambda Functions¶
Lambda functions are small, anonymous functions.
Can define them in line.
increment = lambda a : a + 1
increment(1)
2
# not a lambda function
def lambda_equivalent(a):
output = a + 1
return output
lambda_equivalent(1)
2
Clicker Question #4¶
What would the following return?
my_list = [1, 5, 4, 6, 8, 11, 3, 12]
new_list = list(filter(lambda x: (x%2 == 0), my_list))
new_list
[4, 6, 8, 12]
A)
[1, 5, 11, 3]
B)
[1, 3, 5, 11]
C)
[4, 6, 8, 12]
D)
[1, 5, 4, 6, 8, 11, 3, 12]
E) ¯\_(ツ)_/¯
map¶
map
applies a given function to each element in a collection.
# create a function
def double(val):
return val * 2
# map function to each element of list
my_list = [1, 2, 3, 4]
list(map(double, my_list))
[2, 4, 6, 8]
# Note - we can use lambda functions with map
list(map(lambda x: x *2, my_list))
[2, 4, 6, 8]
Conditional Assignment¶
You can use a conditional within an assignment, to manipulate what gets assigned given some condition.
# variable assignment
condition = False
my_var = 1 if condition else 2
print(my_var)
2
Unpacking¶
You can unpack collection objects with *
, and key, value pairs with **
.
def my_func(xx, yy, zz):
print(xx, yy, zz)
# create list
my_list = [1, 2, 3]
# this will error
my_func(my_list)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-34-e14a904b0af2> in <module>()
1 # this will error
----> 2 my_func(my_list)
TypeError: my_func() missing 2 required positional arguments: 'yy' and 'zz'
# unpack the list
my_func(*my_list)
1 2 3
# create dictionary
my_dict = {'xx' : 1, 'yy' : 2, 'zz' : 3}
# unpack the dictionary
my_func(**my_dict)
1 2 3
Overloading Operators¶
In other words: Nothing in Python is sacred.
Operators and special operations for objects are defined by double underscore methods, which we can overload to change how the object acts.
class Language():
def __init__(self, name):
self.name = name.lower()
# Overload what the printed representation of the object as a string
def __repr__(self):
return "The programming language " + self.name
# Overload the greater than symbol
def __gt__(self, other):
return True if self.name == 'python' else False
Note: “dunder” is how we refer to those double underscore methods
python = Language('python')
perl = Language('perl')
print(python)
The programming language python
python > perl
True