Demonstrate the use of list generation in Python with code examples

  • 2020-04-02 14:47:06
  • OfStack

1 square list

If you want to create a list of 1 to 10 squares, you can do this:


squares = []
for x in range(10):
 squares.append(x**2)

 

This is a simple example, but the list can be created more succinctly using list generation.


squares = [x**2 for x in range(10)]

The simplest list generator starts with a square bracket, an expression inside, followed by a for statement. The list generator always returns a list.

A list of Numbers where 2 goes into 3

In general, you might write something like this:


numbers = []
for x in range(100):
 if x % 3 == 0:
  numbers.append(x)

You can include an if statement in the list generator to conditionally add items to the list. To create a list of Numbers between 0 and 100 divisible by 3, use the list derivation:


numbers = [x for x in range(100) if x % 3 == 0]

3 find the prime number

This is usually done in several lines of code.


noprimes = []
for i in range(2, 8):
 for j in range(i*2, 50, i):
  noprimes.append(j)
primes = []
for x in range(2, 50):
 if x not in noprimes:
  primes.append(x)

However, you can use two list generators to simplify the code.


noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
primes = [x for x in range(2, 50) if x not in noprimes]

The first line of code USES a multilayer for loop in a list generator. The first loop is the outer loop, and the second is the inner loop. To find primes, we first find a list of non-primes. Generate this list of nonprime Numbers by finding multiples of 2 minus 7. Then we loop through the Numbers and see if each number is in the list of non-prime Numbers.

Fixed: as shoyer on reddit pointed out, using sets to find noprimes is more efficient. Since noprimes should contain only unique values, and we frequently check to see if a value exists, we should use collections. The syntax for using a collection is similar to that for using a list, so we can use it like this:


noprimes = set(j for i in range(2, 8) for j in range(i*2, 50, i))
primes = [x for x in range(2, 50) if x not in noprimes]

Nested list dimension reduction

Suppose you have a list of lists or a matrix,


matrix = [[0,1,2,3], [4,5,6,7], [8,9,10,11]]

And you want to reduce it to a one-dimensional list. You can do this:


flattened = []
for row in matrix:
 for i in row:
  flattened.append(i)

Use the list generator:


flattened = [i for row in matrix for i in row]

This USES two for loops to iterate over the entire matrix. The outer (first) loop iterates on rows, and the inner (second) loop iterates on each item in the row.

Simulate multiple coin toss events

Suppose you want to simulate multiple coin flips, where 0 means heads and 1 means tails. You can write the code like this:


from random import random
results = []
for x in range(10):
 results.append(int(round(random())))

Or use list generation to make your code cleaner:


from random import random
results = [int(round(random())) for x in range(10)]

I've used the range function to loop through it 10 times. Each time we round the output of random(). Since the random() function returns a floating-point number from 0 to 1, rounding the output returns either 0 or 1. The Round() function returns floating point data, converts it to an int() and adds it to the list.

Remove vowels from a sentence

Suppose you have a sentence,


sentence = 'Your mother was a hamster'

And you want to remove all the vowels. We can easily do this with a few lines of code:


vowels = 'aeiou'
non_list = []
for l in sentence:
 if not l in vowels:
  non_list.append(l)
nonvowels = ''.join(non_list)

Or you can simplify it by using list generation:


vowels = 'aeiou'
nonvowels = ''.join([l for l in sentence if not l in vowels])

This example USES list generation to create a list of letters whose letters come from the non-vowel of the sentence. We then pass the generated list to the join() function to convert it to a string.

Fixed: as suggested by reddit's atisthis, this example does not require a list generator. The generator is better:


vowels = 'aeiou'
nonvowels = ''.join(l for l in sentence if not l in vowels)

Notice that the brackets have been removed. This is because the join function receives any iterable data, including a list or generator. This syntax without square brackets USES a generator. This produces the same result (as list-generation), as opposed to wrapping all the items into a list before the generator produces the corresponding items during our traversal. This saves us from having to save the entire list into memory, and is more efficient for processing large amounts of data.

  Get a list of file names in the directory

The following code will walk through the files in the my_dir directory and append each file name with the TXT suffix to the files.


import os
files = []
for f in os.listdir('./my_dir'):
 if f.endswith('.txt'):
  files.append(f)

This also simplifies the code using list generation:


import os
files = [f for f in os.listdir('./my_dir') if f.endswith('.txt')]

Or you can get a list of relative paths:


import os
files = [os.path.join('./my_dir', f) for f in os.listdir('./my_dir') if f.endswith('.txt')]

Thanks to rasbt on reddit.

Read the CSV file as a dictionary list

We often need to read and process data from CSV files. One of the most useful ways to work with CSV data is to convert it to a list of dictionaries.


import csv
data = []
for x in csv.DictReader(open('file.csv', 'rU')):
 data.append(x)

You can use list generation to quickly implement:


import csv
data = [ x for x in csv.DictReader(open('file.csv', 'rU'))]

The DictReader class will automatically use the first line of the CSV file as the key property name for the dictionary. The DictReader class returns an object that will traverse all rows of the CSV file. This file object is generated by the open() function. We provide two parameters, open(), the first is the CSV file name, and the second is the schema. In this case, 'rU' has two meanings. As usual, 'r' means open the file in read mode. The 'U' indicates that we will accept the universal newline characters,' n', 'r', and' rn'.

Thanks to blacwidonsfw on reddit.


Related articles: