Python is the Atoms and Molecules of your AI journey. You will never realize this explicitly but you will use it every moment and in every line of your code. Having a quick hand on Python enables you to test new concepts quickly which eventually encourages you to try new ideas on the ground.
In this blog, we will learn many of the important Python stuff that might be new to you Or you must keep it at your fingertips.
1. For loop and List comprehension analogy
List comprehension is the go-to way to iterate in Python, you should seldom use for-Loop. Here, we will try to develop an analogy of list-comprehension with for-loop (because that syntax is the default in our mind)
With the for-loop analogy, you can apply the list comprehension to a deeper level of nesting. Check the Image i.e. how the numeric indicator is mapped between for-loop and list-comprehension
simple_list = ['This', 'is', '10xAI', 'Learning', '!!!']
# ---> [<<<Your expression>>> for elem in simple_list]
[elem.upper() for elem in simple_list]
Output
['THIS', 'IS', '10XAI', 'LEARNING', '!!!']
2. Nested List Comprehension
With the analogy, now it is a cakewalk.
nested_list = [ ['This', 'is'], ['10xAI', 'Learning'], ['It\'s', 'all'], ['about','AI'], ['!','!'] ]
# ---> [<<<Your expression>>> for inner_list in outer_list for elem in inner_list]
[elem for inner_list in nested_list for elem in inner_list]
Output
['This', 'is', '10xAI', 'Learning', "It's", 'all', 'about', 'AI', '!', '!']
3. zip and enumerate
Zip is a handy tool to pack the respective elements of two sequences. Enumerate doesn't need any introduction. So, just placing a simple example
models = ['LR', 'RandomForest', 'DecisionTree', 'SVM', 'KNN']
score = [0.7, 0.9, 0.8, 0.75, 0.72]
# Zipping respective pair
[[tup[0],tup[1]] for tup in zip(models,score)]
# Enumerate with Dict-Comprehension
{id:{tup[0]:tup[1]} for id,tup in enumerate(zip(models,score))}
4. Passing function as parm
Functions are objects too. You can assign and pass them as any other type using its Identifier.
def g(x) : return 10*x
def f(g_x, x): return 1/g_x(x) # Accepts functin as one of the parameters
simple_list = [0.1, 0.2, 0.4, 0.5, 1]
[f(g , i) for i in simple_list] # Passing function as argument
# Can assign another identifier
func_var = g # No parenthesis
[f(func_var , i) for i in simple_list]
Output
[1.0, 0.5, 0.25, 0.2, 0.1]
5. print "sep" and "end" parameters
Know and use these two parameters for the print function.
print(objects, sep=' ', end='\n', file=sys.stdout, flush=False)
end
defines what will be appended at the end of a print statement. Default is a new line, that' why the next print starts from the next line.
sep
defines how two objects will be separated. Default is blank.
You can change both these defaults.
models = ['LR', 'RandomForest', 'DecisionTree', 'SVM', 'KNN']
score = [0.7, 0.9, 0.8, 0.75, 0.72]
# Defaults
for i in range(5):
print(models[i], score[i])
# using sep
for i in range(5):
print(models[i], score[i], sep="==")
# using end
for i in range(5):
print(models[i], score[i], sep="=", end=" | ")
Output
LR=0.7 | RandomForest=0.9 | DecisionTree=0.8 | SVM=0.75 | KNN=0.72 |
6. Throw-away variable unpacking with *
The packing and unpacking of variable are one of the kool stuff in Python. Let's quickly learn some of its variations and extension. Using a * in the right you can ignore the items which are not required.
many_vars = [100, "aqz", 0.002, "ignore"]
# We just need the 100
var, *_ = many_vars # _ is the throw-away variable
print(var)
# If we want to keep all others just for future ref
var, *my_bin = many_vars
print(my_bin) # my_bin is a list
7. Nested sequence unpacking with *
With an * before a sequence will unpack it.
many_vars = [ [100, "aqz"] , [0.002, "ignore"] ]
# Default way, we need the 100
var, *my_bin = many_vars
print(var) # var is the list as due to only 1st level unpacking
# Using *, we need the 100
var, *my_bin = (*many_vars[0],*many_vars[1])
print(var) # var is the list as due to only 1st level unpacking
8. Using set, sorted, reversed
Whenever you need to get the unique values in a sorted manner. Use this
text = "a quick brown fox jumps over the lazy dog"
sorted(set(text))
# Use join for making it String
'_'.join(sorted(set(text)))
# Reversed it
list(reversed(sorted(set(text)))) # Reverse returns an Iterator, so list func applied
Output
'_a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z'
9. Slicing with negative Index and step
First thing first - Python is 0-indexed.
Slice has 3 elements i.e. start, stop, step. The last item is indexed as -1 and the second last is indexed as -2 and son on. The step can be negative. The last index gets excluded.
Let's apply this information.
simple_list = [1, 7, 8, 0, 5, 23]
# with negative Index
simple_list[:-2 ] # From start to second-last element(-2 excluded)
# Trimming
simple_list[1:-1 ] # Very often needed with String
# Alternate Even-Indexed
simple_list[::2 ]
# Alternate Odd-Indexed
simple_list[1::2 ]
# Reversing the list
simple_list[::-1 ] # One of the coolest Python stuff
10. Adding power with ".join"
Join is your friend when you want to get the string from a sequence by concatenating all its elements with a specific character. You can also concatenate with blank.
simple_list = ['This', 'is', '10xAI', 'Learning', '!!!']
' '.join(simple_list)
# With List-comprehension
' '.join([elem.upper() for elem in simple_list])
Output
THIS IS 10XAI LEARNING !!!
11. map with multiple sequences
The map is another very useful built-in function. It takes a function and one or more Iterable and applies the function to the elements of the Iterable. Function argument will be a tuple having a number of elements equal to the number of Iterable
simple_list = [1, 2, 3, 4, 5 ]
def func(x) : return x**2
# Get the square
list(map(func, simple_list)) # Will return an Iterator, so use list
# Use different exponent for different values
exponent_list = [5, 4, 3, 2, 1 ]
def func(x, y) : return x**y
list(map(func, simple_list,exponent_list)) # passing two list, hence function should accept 2 parameters
12. Apply filter on sequence
The filter is another very handy built-in function. It takes a function and an Iterable and return the elements of the Iterable for which the function evaluates to True
simple_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
def odd(x) : return True if x%2!=0 else False
# Get the Odd elements
list(filter(odd, simple_list)) # Will return an Iterator, so use list
# This is the same as this :-)
[elem for elem in simple_list if elem%2!=0]
13. Permutation, Combination with Itertools
Itertools is a handy module in Python when you quickly want to generate a permutation, a combination of product of two sequences.
import itertools
comb = itertools.combinations([1,2,3,4], 3) # all combination(i.e. 2,3 and 3,2 are same ) of length 3
list(comb)
perm = itertools.permutations([1,2,3,4], 3) # all permutation (i.e. 2,3 and 3,2 are different ) of length 3
list(perm)
prod = itertools.product(['A','B'],[1,2,3,4]) # all Cartesian product
list(prod)
14. Generator expression
We can use a Generator Expression i.e. genexps as a simple way to write an inline generator.
It’s work exactly like List Comprehension except,
- Uses ( ) instead of [ ]
- Does not generate a List but an iterator yielding one item at a time i.e. saves memory
- Use it when you want to pass an Iterator but not intended to save
gen = (x*x for x in range(10))
next(gen) #0
next(gen) #1
next(gen) #2
list(gen) # Make a list
# Just like List Comprehension without saving a List in memory
sum(x*x for x in range(10)) # Don’t need the extra Brackets when used with a function
15. Iterable/Iterator
This is quite confusing sometimes. Though you may sail through w/o understanding these concepts.
Something is Iterable means we can loop over its elements
This is the collection we use in for loop i.e. for elem in Iterable:
An Iterator is more of the background implementation to make the loop happening
Technically -
Iterable, when called on iter() built-In function return an Iterator Iterator has a next method that returns the next element and moves the position to the new next.
s = 'cat'
t = iter(s) # Made an Iterator
next(t) # call the next built-in function
# Output 'c'
next(t)
# Output 'a'
Read this Answer at SO
stackoverflow.com/a/9884501/2187625