cells:
- markdown: |
# Advanced Python: List/dict comprehensions, generator expressions
### Prabhu Ramachandran
### The FOSSEE Python group &
### Department of Aerospace Engineering
### IIT Bombay
metadata:
slideshow:
slide_type: slide
- markdown: |
## Introduction
- A convenient way to quickly create lists
- Lets say we have the following
metadata:
slideshow:
slide_type: slide
- code: |
sqr = []
for i in range(5):
sqr.append(i*i)
- markdown: |
Is done easily with the following
- code: |
sqr = [i*i for i in range(5)]
sqr
metadata:
slideshow:
slide_type: fragment
- markdown: |
## More examples
- Concise, readable, and quick
metadata:
slideshow:
slide_type: slide
- code: |
[2*x + 1 for x in range(5)]
- code: |
data = [-1, -2, 3, 4]
[abs(x) for x in data]
- code: |
names = ['Amar', 'Akbar', 'Antony']
[x.upper() for x in names]
- code: |
[(len(x), x) for x in names]
- markdown: |
## Filtering elements
- Filter elements using `if` clauses
metadata:
slideshow:
slide_type: slide
- code: |
data = [-1, -2, 3, 4]
positive = [x for x in data if x > 0]
positive
- code: |
not_in_data = [x for x in range(-2, 5) if x not in data]
not_in_data
- markdown: |
## More complex comprehensions
- One can have many `for` and `if` clauses
metadata:
slideshow:
slide_type: slide
- code: |
[(i, j) for i in range(3) for j in range(2)]
- code: |
[(i, j) for i in range(3) for j in range(2) if i > j]
- code: |
[(i, j) for i in range(4) if i%2 for j in range(4) if i > j]
- code: |
[(i, j) for i in range(4) if i%2 for j in range(4) if (i > j or j%2)]
- code: |
[(i, j) for i in range(4) if i%2 for j in range(4) if i > j if j%2]
- markdown: |
## Observations
- Powerful and convenient.
- Can supply multiple `for` and `if` clauses
- Always create lists
- What if we want a generator?
metadata:
slideshow:
slide_type: slide
- markdown: |
## Generator expressions
- Like list comprehensions but:
- do not create lists
- and create a generator
- Values are generated when needed
- Memory efficient
metadata:
slideshow:
slide_type: slide
- code: |
gexp = (i*i for i in range(5))
- code: |
sum(gexp)
metadata:
slideshow:
slide_type: fragment
- code: |
from math import sin
max(sin(x) for x in range(10))
metadata:
slideshow:
slide_type: fragment
- markdown: |
## More examples
- `zip` is a handy function
metadata:
slideshow:
slide_type: slide
- code: |
a = [1.0, 2.0, 3.1]
b = [-1.5, -1.0, -0.5]
zip(a, b)
- code: |
list(zip(a, b))
- code: |
list(zip('hello', 'world'))
- code: |
list(zip(range(5), 'hello'))
- code: |
sum(x*y for x, y in zip(a, b))
- markdown: |
## Dictionary comprehensions
- Similar to list comprehensions
- Creates a dictionary easily
metadata:
slideshow:
slide_type: slide
- code: |
{x: len(x) for x in ('cat', 'dog', 'mouse')}
- code: |
{x: x%2 == 0 for x in range(0, 5)}
- markdown: |
## Summary
- List comprehensions
- Generator expressions
- Dictionary comprehensions
- The `zip` builtin
metadata:
slideshow:
slide_type: slide
- markdown: |
## Exercise: even number list comprehension
Write a simple list comprehension that generates the first 5 even
numbers as a list.
metadata:
slideshow:
slide_type: slide
- code: |
[2*i for i in range(1, 6)]
metadata:
slideshow:
slide_type: fragment
- markdown: |
## Exercise: positive `sin` values
Write a list comprehension that generates only positive values of the
`math.sin` when applied to the first 10 values between $0$ to $2 \pi$.
metadata:
slideshow:
slide_type: slide
- code: |
from math import sin, pi
[sin(i*2*pi/9) for i in range(0, 10) if sin(i*2*pi/9) > 0]
metadata:
slideshow:
slide_type: fragment
- code: |
# or
r = [sin(i*2*pi/9) for i in range(0, 10)]
[x for x in r if x > 0]
metadata:
slideshow:
slide_type: fragment
- markdown: |
## Exercise: two letter permutations of 'hello'
Using a list comprehension, write all possible 2 letter permutations of
the word 'hello', do not worry about repetitions.
metadata:
slideshow:
slide_type: slide
- code: |
word = 'hello'
[x + y for x in word for y in word]
metadata:
slideshow:
slide_type: fragment
- markdown: |
## Exercise: unique two letter permutations of 'hello'
Write all possible 2 letter permutations of the word 'hello', this time
show only the unique ones.
metadata:
slideshow:
slide_type: slide
- code: |
word = 'hello'
set(x + y for x in word for y in word)
metadata:
slideshow:
slide_type: fragment
- code: |
# Or better to use a generator expression
set(x + y for x in word for y in word)
metadata:
slideshow:
slide_type: fragment
- markdown: |
## Exercise: list of tuples
Using a list comprehension, create a list of tuples of the form `(x, x*x,
x*x*x)` for the first 5 integers starting at 1.
metadata:
slideshow:
slide_type: slide
- code: |
[(x, x*x, x*x*x) for x in range(1, 6)]
metadata:
slideshow:
slide_type: fragment
- markdown: |
## Exercise: simple dictionary comprehension
Create a dictionary with the keys being the lowercase characters of the
English alphabet and the value being an empty list.
metadata:
slideshow:
slide_type: slide
- code: |
{x: [] for x in 'abcdefghijklmnopqrstuvwxyz'}
metadata:
slideshow:
slide_type: fragment
- markdown: |
## Exercise: another simple dict comprehension
Create a dictionary with the keys being the lowercase words (only the
first three characters) denoting the day of the week and the value being
an integer corresponding to each with 0 being 'mon' and 6 'sun'.
metadata:
slideshow:
slide_type: slide
- code: |
{x: i for i, x in enumerate(('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'))}
metadata:
slideshow:
slide_type: fragment
- code: |
# Or
{x: i for i, x in enumerate('mon tue wed thu fri sat sun'.split()) }
metadata:
slideshow:
slide_type: fragment
- markdown: |
## Exercise: max `sin` generator expression
Using a generator expression find the maximum value of `math.sin` when
applied to the first 100 values between $0$ to $2 \pi$.
metadata:
slideshow:
slide_type: slide
- code: |
from math import sin, pi
max(sin(i*2*pi/99) for i in range(0, 100))
metadata:
slideshow:
slide_type: fragment
# The lines below here may be deleted if you do not need them.
# ---------------------------------------------------------------------------
metadata:
kernelspec:
display_name: Python 3
language: python
name: python3
language_info:
codemirror_mode:
name: ipython
version: 3
file_extension: .py
mimetype: text/x-python
name: python
nbconvert_exporter: python
pygments_lexer: ipython3
version: 3.5.2
rise:
scroll: true
transition: none
nbformat: 4
nbformat_minor: 2