List comprehension methods in Python
The need for Python
If no already obvious, Python is a language of comprehensions itself as it supports modularity, object-oriented programming, functional programming, as well as the lack of any(or all) of them, so there is no restriction like Java where everything is an object or like Haskell where everything is a function. Depending on the purpose, you are the architect of the code.
Compared to C++ we may rewrite 9 lines of code in only 2 lines.
C++
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
cout << a + b + c << endl;
return 0;
}
Python
a, b, c = map(int, input().split())
print(a + b + c)
Lists in python
The basic data types in Python are:
- integer
- boolean
- floating-point
- string
In contrast to C/C++, the arrays are not statically typed, so you don’t need to know the type of the values that are going to be stored; of course the array will take up enough memory to accommodate any possible type — the equivalent of a void pointer from C. The arrays are in 98% of cases implemented using lists, and for matrices are used …. lists in lists! How? Well, below is a code example
Python code
array1 = [1, 5, 3, 0, 5]
array2 = [1, 2, 3, 4, 5]
matrix1 = [[1, 2, 3],
[5, 2, 4],
[5, 1, 3]]
matrix2 = [[5, 2, 3],
[6, 2, 4],
[2, 3, 2]]
print(array1)
print(matrix2)
[1, 5, 3, 0, 5]
[[5, 2, 3], [6, 2, 4], [2, 3, 2]]
List declaration
Python supports a wide range of declaration and initialization methods based on tuples, lists, dictionaries, ranges and logical conditions as filters.
Splitting a natural interval in even and odd numbers
l1 = [i for i in range(1, 20)]
l2 = [i for i in l1 if i % 2 == 0]
l3 = [i for i in l1 if i % 2 == 1]
print(l1)
print(l2)
print(l3)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[2, 4, 6, 8, 10, 12, 14, 16, 18]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
Dividing N natural numbers in classes of remainder modulo K
k = 10
array = [i for i in range(1, 31)]
remainders = [[i for i in array if i % k == j] for j in range(k)]
print(array)
print(remainders)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
[[10, 20, 30], [1, 11, 21], [2, 12, 22], [3, 13, 23], [4, 14, 24], [5, 15, 25], [6, 16, 26], [7, 17, 27], [8, 18, 28], [9, 19, 29]]
Applying a lambda function over the elements
ar = [13, 24, 52, 12, 83, 84, 25, 39]
def hash_function(x: int) -> int:
a = x >> 3
b = x % 8
return (a + 2 * b) % 16
hash_ar = [hash_function(i) for i in ar]
print(hash_ar)
[11, 3, 14, 9, 0, 2, 5, 2]
Reverse all strings from a list
words = ["Medium", "is", "the", "coolest", "tech", "blog", "ever"]
reversed_words = [word[::-1] for word in words]
print(reversed_words)
[‘muideM’, ‘si’, ‘eht’, ‘tselooc’, ‘hcet’, ‘golb’, ‘reve’]
Apply XOR with ease on ciphertext and key(and many crypto applications as well)
# suppose we know the secret 'aresdv' and a random-valued cyphertext
cyphertext = [32, 28, 1, 1, 1, 31]
key = list(ord(i) for i in 'aresdv')
# now we can compute the plaintext with ease
plaintext = [i^j for i, j in zip(cyphertext, key)]
print(plaintext)
# and convert the ascii to characters
plaintext_ascii = [chr(i) for i in plaintext]
print(plaintext_ascii)
[65, 110, 100, 114, 101, 105]
[‘A’, ’n’, ‘d’, ‘r’, ‘e’, ‘i’]
than checking it out everything was correct we can compute back the cyphertext knowing the actual plaintext
cypher_again = [ord(chr(i^j)) for i, j in zip(plaintext, key)]
print(cypher_again)
[32, 28, 1, 1, 1, 31]
Applying functional programming
filter
words = {'I', 'am', 'a', 'programmer', 'writing', 'on', 'medium'}
small_words = filter(lambda x: True if len(x) < 5 else False, words)
for idx, w in enumerate(small_words):
print(f'{idx}: {w}', end=' ')
# OUTPUT:
# 0:am 1:on 2:a 3:I
Based on a bigger list we can create a newer one filtering it in concordance with a criteria of our choice, in this case only the words that we consider sufficient enough to be called small.
map
n = {1, 2, 3, 4, 5, 6}
squared_n = map(lambda x: x**2, n)
for idx, n2 in enumerate(squared_n):
print(f'{idx}:{n2}', end=' ')
# OUTPUT:
# 0:1 1:4 2:9 3:16 4:25 5:36
What this actually does is explained mathematically right below
Obviously, the square function is just one of the most common ones, but imagine that you could have just another list or a tuple as the argument and the output could have been another filtered list or just the sum of the even elements.
reduce
One very import aspect that you must consider especially when falling for using reduce, that is the order of elements. If you want it to be conserved you must use lists or tuples! In the case of sets(the structure which doesn’t care for order or duplicates, you may get random outputs sometimes:
import functools
set_words = {'Let\'s', 'make', 'a', 'sentence', 'out', 'of', 'words'}
tuple_words = ('Let\'s', 'make', 'a', 'sentence', 'out', 'of', 'words')
list_words = ['Let\'s', 'make', 'a', 'sentence', 'out', 'of', 'words']
set_sentence = functools.reduce(lambda x, y: x + ' ' + y, set_words)
tuple_sentence = functools.reduce(lambda x, y: x + ' ' + y, tuple_words)
list_sentence = functools.reduce(lambda x, y: x + ' ' + y, list_words)
print('Output for ' + str(type(set_words)) + ': ' + set_sentence,
'Output for ' + str(type(tuple_words)) + ': ' + tuple_sentence,
'Output for ' + str(type(list_words)) + ': ' + list_sentence,
end='', sep='\n===================================================\n')
# OUTPUT:
# Output for <class 'set'>: of words out a Let's sentence make
# ===================================================
# Output for <class 'tuple'>: Let's make a sentence out of words
# ===================================================
# Output for <class 'list'>: Let's make a sentence out of words
In contrast to this case of factorizing numbers up where a set is undesirable because of possible repetitions of specific numbers:
set_factors = {2, 3, 4, 2}
tuple_factors = (2, 3, 4, 2)
list_factors = [2, 3, 4, 2]
set_product = functools.reduce(lambda x, y: x*y, set_factors)
tuple_product = functools.reduce(lambda x, y: x*y, tuple_factors)
list_product = functools.reduce(lambda x, y: x*y, list_factors)
print('Output for ' + str(type(set_factors)) + ': ' + str(set_product),
'Output for ' + str(type(tuple_factors)) + ': ' + str(tuple_product),
'Output for ' + str(type(list_factors)) + ': ' + str(list_product),
end='', sep='\n===================================================\n')
# OUTPUT:
# Output for <class 'set'>: 24
# ===================================================
# Output for <class 'tuple'>: 48
# ===================================================
# Output for <class 'list'>: 48
In conclusion, python works just fine as it is with lots of useful features for you to code, the big responsibility is to know what exactly you choose and the reasons back the curtain.
If you liked it…
- Please consider clapping and following me! 👏
- If you have suggestions/preferred topics you want me to write about, tell me down in a comment
- Thanks anyways, if you reached so far reading my article!