Skip to main content

List Comprehension in Python

     Comprehensions in Python provide us with a short and concise way to construct new sequences.

Why We use List Comprehension?:

  • The code is more concise.
  • The code is generally more readable.
  • The code, in most cases, will run faster.
  • Efficient Memory Management

What is Python List Comprehension?

Suppose you want to take the letters in the word ‘anxiety’, and want to put them in a list. 

Using a for loop, you would:

>>> mylist=[]
>>> for i in 'anxiety':
mylist.append(i)
>>> mylist

Output

[‘a’, ‘n’, ‘x’, ‘i’, ‘e’, ‘t’, ‘y’]



But with a Python list comprehension, you can do this in one line:

>>> [i for i in 'anxiety']

Output

[‘a’, ‘n’, ‘x’, ‘i’, ‘e’, ‘t’, ‘y’]

List Comprehensions Syntax

A list comprehension creates a new list by applying an expression to each element of an iterable. The most basic

form is:

[ <expression> for <element> in <iterable> ]

There's also an optional 'if' condition:

[ <expression> for <element> in <iterable> if <condition> ]


Each <element> in the <iterable> is plugged in to the <expression> if the (optional) <condition> evaluates to true. All results are returned at once in the new list. 


To create a list of squared integers:

squares = [x * x  for x in (1, 2, 3, 4)]

# squares: [1, 4, 9, 16]


The for expression sets x to each value in turn from (1, 2, 3, 4). The result of the expression x * x is appended to an internal list. The internal list is assigned to the variable squares when completed.

Besides a speed increase (as explained here), a list comprehension is roughly equivalent to the following for-loop:

squares = []

for x in (1, 2, 3, 4):

squares.append(x * x)

# squares: [1, 4, 9, 16]


The expression applied to each element can be as complex as needed:

# Get a list of uppercase characters from a string

[s.upper() for s in "Hello World"]

# ['H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D']

# Strip off any commas from the end of strings in a list

[w.strip(',') for w in ['these,', 'words,,', 'mostly', 'have,commas,']]

# ['these', 'words', 'mostly', 'have,commas']

# Organize letters in words more reasonably - in an alphabetical order

sentence = "Beautiful is better than ugly"

["".join(sorted(word, key = lambda x: x.lower())) for word in sentence.split()]

# ['aBefiltuu', 'is', 'beertt', 'ahnt', 'gluy']


else:

else can be used in List comprehension constructs, but be careful regarding the syntax. The if/else clauses should be used before for loop, not after:

# create a list of characters in apple, replacing non vowels with '*'

# Ex - 'apple' --> ['a', '*', '*', '*' ,'e']

[x for x in 'apple' if x in 'aeiou' else '*']

#SyntaxError: invalid syntax

# When using if/else together use them before the loop

[x if x in 'aeiou' else '*' for x in 'apple']

#['a', '*', '*', '*', 'e']



Double Iteration

Order of double iteration [... for x in ... for y in ...] is either natural or counter-intuitive. The rule of

thumb is to follow an equivalent for loop:

def foo(i):

    return i, i + 0.5

for i in range(3):

    for x in foo(i):

    yield str(x)

This becomes:

[str(x)

for i in range(3)

for x in foo(i)

]

This can be compressed into one line as [str(x) for i in range(3) for x in foo(i)]


In-place Mutation and Other Side Effects

Before using list comprehension, understand the difference between functions called for their side effects (mutating, or in-place functions) which usually return None, and functions that return an interesting value.

Many functions (especially pure functions) simply take an object and return some object. An in-place function modifies the existing object, which is called a side effect. Other examples include input and output operations such as printing.

list.sort() sorts a list in-place (meaning that it modifies the original list) and returns the value None. Therefore, it

won't work as expected in a list comprehension:

[x.sort() for x in [[2, 1], [4, 3], [0, 1]]]

# [None, None, None]

Instead, sorted() returns a sorted list rather than sorting in-place:


[sorted(x) for x in [[2, 1], [4, 3], [0, 1]]]

# [[1, 2], [3, 4], [0, 1]]

Using comprehensions for side-effects is possible, such as I/O or in-place functions. Yet a for loop is usually more

readable. While this works in Python 3:

[print(x) for x in (1, 2, 3)]

Instead use:

for x in (1, 2, 3):

print(x)


Whitespace in list comprehensions

More complicated list comprehensions can reach an undesired length, or become less readable. Although less  common in examples, it is possible to break a list comprehension into multiple lines like so:

[

x for x

in 'foo'

if x not in 'bar'

]

Conditional List Comprehensions

Given a list comprehension you can append one or more if conditions to filter values.

[<expression> for <element> in <iterable> if <condition>]

For each <element> in <iterable>; if <condition> evaluates to True, add <expression> (usually a function of

<element>) to the returned list.

For example, this can be used to extract only even numbers from a sequence of integers:

[x for x in range(10) if x % 2 == 0]

# Out: [0, 2, 4, 6, 8]

The above code is equivalent to:

even_numbers = []

for x in range(10):

    if x % 2 == 0:

    even_numbers.append(x)

print(even_numbers)


# Out: [0, 2, 4, 6, 8]


example:

[x if x % 2 == 0 else None for x in range(10)]

# Out: [0, None, 2, None, 4, None, 6, None, 8, None]


items:

<value-if-condition-is-true> if <condition> else <value-if-condition-is-false>

This becomes more obvious if you combine it with other operators:

[2 * (x if x % 2 == 0 else -1) + 1 for x in range(10)]

# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]

List Comprehensions with Nested Loops

List Comprehensions can use nested for loops. You can code any number of nested for loops within a list comprehension, and each for loop may have an optional associated if test. When doing so, the order of the for constructs is the same order as when writing a series of nested for statements. The general structure of list

comprehensions looks like this:

[ expression for target1 in iterable1 [if condition1]

for target2 in iterable2 [if condition2]...

for targetN in iterableN [if conditionN] ]

For example, the following code flattening a list of lists using multiple for statements:

data [[12][34][56]]

output []

for each_list in data:

for element in each_list:

output.append(element)

print(output)

# Out: [1, 2, 3, 4, 5, 6]

can be equivalently written as a list comprehension with multiple for constructs:

data [[12][34][56]]

output [element for each_list in data for element in each_list]

print(output)

# Out: [1, 2, 3, 4, 5, 6]

 Dictionary Comprehensions

A dictionary comprehension is similar to a list comprehension except that it produces a dictionary object instead of a list.


{x: x * x for x in (1, 2, 3, 4)}

# Out: {1: 1, 2: 4, 3: 9, 4: 16}

which is just another way of writing:

dict((x, x * x) for x in (1, 2, 3, 4))

# Out: {1: 1, 2: 4, 3: 9, 4: 16}

As with a list comprehension, we can use a conditional statement inside the dict comprehension to produce only the dict elements meeting some criterion.


{name: len(name) for name in ('hi', 'hello','python') if len(name) > 6}

# Out: {'Exchange': 8, 'Overflow': 8}

Or, rewritten using a generator expression.


dict((name, len(name)) for name in ('hi', 'hello'python') if len(name) > 6)

# Out: {'Exchange': 8, 'Overflow': 8}

Starting with a dictionary and using dictionary comprehension as a key-value pair filter

initial_dict = {'x': 1, 'y': 2}

{key: value for key, value in initial_dict.items() if key == 'x'}

# Out: {'x': 1}

Merging Dictionaries

Combine dictionaries and optionally override old values with a nested dictionary comprehension.

dict1 = {'w': 1, 'x': 1}

dict2 = {'x': 2, 'y': 2, 'z': 2}

{k: v for d in [dict1, dict2] for k, v in d.items()}

# Out: {'w': 1, 'x': 2, 'y': 2, 'z': 2}

However, dictionary unpacking (PEP 448) may be a preferred.

Python 3.x Version ≥ 3.5

{**dict1, **dict2}

# Out: {'w': 1, 'x': 2, 'y': 2, 'z': 2}



Comments

Popular posts from this blog

Is-A and Has-A relationships in python

  In object-oriented programming, the concept of IS-A is a totally based on Inheritance, which can be of two types Class Inheritance or Interface Inheritance. It is just like saying "A is a B type of thing". For example, Apple is a Fruit, Car is a Vehicle etc. Inheritance is uni-directional. For example, House is a Building. But Building is not a House. #Is-A relationship --> By Inheritance class  A:    def   __init__ ( self ):      self .b= 10    def   mym1 ( self ):      print ( 'Parent method' ) class  B(A):    def   mym2 ( self ):      print ( 'Child method' ) d = B() d.mym1() #output: Parent method d.mym2() #output: Child method HAS-A Relationship:  Composition(HAS-A) simply mean the use of instance variables that are references to other objects. For example Maruti has Engine, or House has Bathroom. Let’s understand...

Magic Methods in Python

  What Are Dunder Methods ? In Python, special methods are a set of predefined methods you can use to enrich your classes.  They are easy to recognize because they start and end with double underscores, for example  __init__  or  __str__ . Dunder methods let you emulate the behavior of built-in types.  For example, to get the length of a string you can call  len('string') . But an empty class definition doesn’t support this behavior out of the box: These “dunders” or “special methods” in Python are also sometimes called “magic methods.” class NoLenSupport : pass >>> obj = NoLenSupport () >>> len ( obj ) TypeError : "object of type 'NoLenSupport' has no len()" To fix this, you can add a  __len__  dunder method to your class: class LenSupport : def __len__ ( self ): return 42 >>> obj = LenSupport () >>> len ( obj ) 42 Object Initialization:  __init__ "__init __ ...

Inheritance and Types in Python

  Inheritance   Creating a new class from existing class is known as inheritance . The class from which features are inherited is known as base class and the class into which features are derived into is called derived class . Syntax: class  derived- class (base  class ):       < class -suite>      Inheritance promotes reusability of code by reusing already existing classes.  Inheritance is used to implement  is-a  relationship between classes.   Following hierarchy is an example representing inheritance between classes:   Single inheritance   When a derived class inherits only from syntax, the base class is called single inheritance. If it has one base class and one derived class it is called single inheritance.   Diagram     Syntax class  A:  #parent class         #some code       class  b(A):...