ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • List, Dictionary, Set Comprehensions, and Difference between List Comprehensions and Generator expressions
    DynamicPL/Python 2019. 10. 22. 16:56

    1. Overview

    After reading this article you’ll learn:

    • What are the list comprehensions in Python
    • What are set comprehensions and dictionary comprehensions

    2. Definition

    List comprehensions provide us with a simple way to create a list based on some iterable. During the creation, elements from the iterable can be conditionally included in the new list and transformed as needed. An iterable is something you can loop over

    The components of a list comprehension are:

    • Output Expression (Optional)
    • Iterable
    • Iterator variable which represents the members of the iterable

     

    numbers = [1, 2, 3, 4, 5, 6, 18, 20]
    squares = ["small" if number < 10 else "big" for number in numbers if number % 2 == 0 if number % 3 == 0]
    print(squares)
    
    #output
    ['small', 'big']

    3. Comparison between List Comprehensions and loops

    The list comprehensions are more efficient both computationally and in terms of coding space and time than a for a loop. Typically, they are written in a single line of code.

    Let’s see how much more space we’ll need to get the same result from the last example using a for a loop.

    3.1 Convertable

    Every list comprehension can be rewritten as a for loop, but not every for loop can be rewritten as a list comprehension.

    3.2 Speed

    import timeit
    
    def squares(size):
        result = []
        for number in range(size):
            result.append(number*number)
        return result
    
    def squares_comprehension(size):
        return [number*number for number in range(size)]
    
    print(timeit.timeit("squares(50)", "from __main__ import squares", number = 1_000_000))
    print(timeit.timeit("squares_comprehension(50)", "from __main__ import squares_comprehension", number = 1_000_000))
    
    #output
    6.255051373276501
    3.7140220287915326

    The list comprehension implementation will be faster in all cases.

    3.3 Readability

     

    numbers = [1, 2, 3, 4, 5, 6, 18, 20]
    squares = [
        "small" if number < 10 else "big" 
        for number in numbers 
        if number % 2 == 0 
        if number % 3 == 0]
    print(squares)
    
    #output
    ['small', 'big']

    3.4 Nested Feature

    3.4.1 Nested For Loops

    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    
    flattened = []
    for row in matrix:
        for item in row:
            flattened.append(item)
            
    print(flattened)
    
    #output
    [1, 2, 3, 4, 5, 6, 7, 8, 9]

    We can achieve the same result using a list comprehension.
    Tip: the order of the for clauses remain the same as in the original for loops.

    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    flattened = [item for row in matrix for item in row]        
    print(flattened)
    
    #output
    [1, 2, 3, 4, 5, 6, 7, 8, 9]

    3.4.2 Nested List Comprehensions

     

    matrix = [[item for item in range(5)] for row in range(3)]
    print(matrix)
    
    #output
    [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

    The "range" type represents an immutable sequence of numbers and is commonly used for looping a specific number of times in "for" loops

    3.5 Comparison between List Comprehensions and map and filter

    List comprehensions are a concise notation borrowed from the functional programming language Haskell. We can think of them like syntactic sugar for the filter and map functions.

    We have seen that list comprehensions can be a good alternative to "for" loops because they are more compact and faster.

    3.5.1 Lambda Function

    Lambda functions are small anonymous functions. They can have any number of arguments but can have only one expression.

    Mostly, the lambda functions are passed as parameters to functions which expect a function object as one of their parameters like map and filter.

    3.5.2 Map Function

    The map function returns an iterator that applies a function to every item of iterable, yielding the results. Let’s compare it with a list comprehension.

    # Map
    numbers = [1, 2, 3, 4, 5]
    squares = list(map(lambda x: x**2, numbers))
    print(squares)
    
    # List Comprehension
    numbers = [1, 2, 3, 4, 5]
    squares = [number**2 for number in numbers]
    print(squares)
    
    #output
    [1, 4, 9, 16, 25]
    [1, 4, 9, 16, 25]

    3.5.3 Filter Function

     

    # Filter
    numbers = [1, 2, 3, 4, 5]
    filtered = list(filter(lambda x: x % 2 == 0, numbers))
    print(filtered)
    
    # List Comprehension
    numbers = [1, 2, 3, 4, 5]
    filtered = [number for number in numbers if number % 2 == 0]
    print(filtered)
    
    #output
    [2, 4]
    [2, 4]

    3.6 Other Comprehensions

    In Python, we have also dictionary comprehensions and set comprehensions. All the principles we saw are the same for these comprehensions, too. We just have to know some very little details to create a dictionary or set comprehensions.

    3.6.1 Dictionary Comprehensions

    To create a dictionary comprehension we just need to change the brackets [] to curly braces {}. Additionally, in the output expression, we need to separate key and value by a colon : .

    prices = {"beer": 2, "fish": 5, "apple": 1}
    float_prices = {key:float(value) for key, value in prices.items()}
    print(float_prices)
    
    #output
    {'beer': 2.0, 'fish': 5.0, 'apple': 1.0}

    3.6.2 Set Comprehensions

    To create a set comprehension we only need to change the brackets [] to curly braces {}.

    numbers = [10, 10, 20, 30, 12, -20, 0, 1]
    unique_squares = {number**2 for number in numbers}
    print(unique_squares)
    
    #output
    {0, 1, 100, 144, 400, 900}

    4. Generator expressions

    Python also has something called generator expressions. They are very similar to the list comprehensions. The difference is that they use round brackets (). Also, they don’t store the list in memory. They use the lazy evaluation technique. And generator expression will be exhausted after one cycle.

    List comprehensions aren’t useful if you’re working with iterators that return an infinite stream or a very large amount of data. Generator expressions are preferable in these situations.

    5. Reference

    https://towardsdatascience.com/python-basics-list-comprehensions-631278f22c40

    'DynamicPL > Python' 카테고리의 다른 글

    Slice  (0) 2019.10.28
    Sequence  (0) 2019.10.26
    iterator, iterable, iteration, iterator protocol, generator functions, generator expressions, and lazy evaluation  (0) 2019.10.22
    Asterisk(*) of Python  (0) 2019.10.18
    Data Structure in Python  (0) 2019.10.18

    댓글

Designed by Tistory.