Skip to the content.

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

-

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

Iterator

-

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:

  1. The for statement calls iter() on the container object.
  2. iter() returns an iterator object that defines the method next(), which accesses elements in the container one at a time.
  3. 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

-

The End

Parrot