Part 12
-
Conditional Expressions
-
What Is It?
Conditional expressions are sometimes referred to as ternary operator.
In essence, a conditional expression is a simplified way to express an conditional statement.
-
The Problem
Even a simple condition can take many lines of code to be expressed using a traditional conditional statement.
def conditional_statement(value: bool) -> bool:
if(value):
return True
else:
return False
conditional_statement(True)
# True
conditional_statement(False)
# False
-
The Solution
Conditional expressions can be used to express conditional logic more concisely.
The syntax takes the following format:
value = true-expr if condition else false-expr
def conditional_statement(value: bool) -> bool:
return True if value == True else False
-
Readability Counts
Don’t automatically assume that concise is always better. In some cases, it may be worth having code that is more drawn out and readable over shorter and hard to read code.
-
List Comprehensions
-
What Is It?
List Comprehensions provide a concise way to create lists.
-
Why?
Suppose you want to generate a list with only items that meet a certain criteria.
output = []
for value in range(10):
if value > 5:
output.append(str(value))
output
# ['6', '7', '8', '9']
-
How
The same code can be simplified with list comprehensions.
The syntax takes the following format:
list_comp = [expr for value in collection if condition]
ouput = [str(value) for value in range(10) if value > 5]
output
# ['6', '7', '8', '9']
-
Breaking It Down
- Expression for final value
- for clause (iteration)
- if clause (conditional to determine which items should be included)
-
Dictionary Comprehensions
-
How
The syntax takes the following format:
dict_comp = {key-expr : value-expr for value in collection if condition}
people = ['Chris', 'Dolio', 'Froilan', 'Kris', 'Roberto']
dict_comp = {person : person.upper() for person in people if len(person) > 4}
dict_comp
{'Chris': 'CHRIS', 'Dolio': 'DOLIO', 'Froilan': 'FROILAN', 'Roberto': 'ROBERTO'}
-
Set Comprehensions
-
How
The syntax takes the following format:
set_comp = {expr for value in collection if condition}
nums = [1, 2, 3, 4, 5]
odds_squared = {num ** 2 for num in nums if num % 2 != 0}
odds_squared
# {1, 9, 25}
-
Iterables / Iterator
-
What Is It?
Iterable
- An iterable is an object which one can iterate over.
- An iterable generates an iterator when it is passed to the iter() method.
Iterator
- An iterator is an object which is used to iterate over an iterable object using the next() method.
- Iterators have the next() method which returns the next item of the object.
-
How Does It Work?
As we’ve seen, most container objects can be looped over using a for statement.
programming_languages = ['c', 'python', 'R', 'java']
for language in programming_languages:
print(language)
# c
# python
# R
# java
-
Behind the scences:
- The for statement calls iter() on the container object.
- iter() returns an iterator object that defines the method next(), which accesses elements in the container one at a time.
- When there are no more elements, next() raises a StopIteration exception which tells the for loop to terminate.
-
Iteration Breakdown
programming_languages = ['c', 'python', 'R', 'java'] # container object
iterator_object = iter(programming_languages) # 1
print(next(iterator_object)) # 2
# c
print(next(iterator_object)) # 2
# python
print(next(iterator_object)) # 2
# R
print(next(iterator_object)) # 2
# java
print(next(iterator_object)) # 3
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# StopIteration
-
Creating Iterator Class
class Skipper:
def __init__(self, data):
self.data = data
self.index = 0
self.last = len(self.data)
def __iter__(self):
return self
def __next__(self):
if self.index == self.last:
raise StopIteration
self.index = self.index + 2
return self.data[self.index]
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
skipper = Skipper(nums)
for num in skipper:
print(num)
# 3
# 5
# 7
# 9
-
Using LCs instead of Higher Order Functions
Genius = ["Jerry", "Jack", "tom", "yang"]
L1 = filter(lambda a: len(a) < 4, Genius)
print(list(L1))
# ['tom']
L2 = [a for a in Genius if len(a) < 4]
print(L2)
# ['tom']
-
Generators
-
What Is It?
Generators are a simple and powerful tool for creating iterators. Generator objects are used to lazily iterate a sequence by levaraging the power of iteration.
-
How Does It Work?
Generators are written like regular functions but use a yield statement whenever they want to return data. Each time next is called on it, the generator resumes where it left off.
def skipper(data):
index = 0
for item in data:
index += 2
if(len(data) > index):
yield data[index]
for num in skipper([1, 2, 3, 4, 5, 6, 7, 8, 9 , 10]):
print(num)
# 3
# 5
# 7
# 9
-
Generator Expressions
-
What Is It?
A Generator expression is another way to create a generator.
-
How Does It Work?
The second code block is a generator expression which is equivalent to the first code block. This is very similar to generator lists. Use parentheses instead of square backets.
def square_gen():
for x in range(5):
yield x ** 2
gen = square_gen()
print(gen)
# <generator object square_gen at 0x103010a98>
gen = (x ** 2 for x in range(5))
print(gen)
# <generator object <genexpr> at 0x103010a20>
-
Generator memory usage
large_list = [x for x in range(1_000_000)]
large_list_g = (x for x in range(1_000_000))
print(large_list.__sizeof__())
print(large_list_g.__sizeof__())
# 8697440
# 96