Python programming handbook part-1

krishnaprasad k
Nerd For Tech
Published in
5 min readOct 2, 2021

--

Python is one of the most widely used and powerful programming languages used by many web developers,machine learning practitioners…list goes on and on, but while we use the python programming languages are we using all the features provided by it!!. Well this is the first of series of article investigating some of the powerful but widely unused programming practices in python.

In this article we will be focusing on following python data structures. We will not be going into the basics of these data structures so those who are not familiar with python 2 or python 3 may find difficulty in understanding some of the concepts explained in this article.

  • List
  • Tuple
  • Dictionaries
  • Set

An array of elements

The most fundamental and widely used mutable and mixed type data structure is a list. Considering most of you all comfortable with handling list data type let us jump straight into list comprehensions.

List comprehensions and generator expressions are two quick ways to build a sequence of elements in python. Among the programming community list comprehensions are generally called list-comps and and generator expressions are called gen-exps.

Constructing a list using list comprehensions

symbols = "abcdefg"
lis1 = [ord(sym) for sym in symbols]
print(lis1)
>>> [97, 98, 99, 100, 101, 102, 103]

My aim is to construct a list containing Unicode substitutions for the above symbols “abcdefg”. The above example shows the construction of such a list using list comprehensions.

In python code, line breaks are ignored in pairs of symbols like { },( ),[ ]. So you can build multiple line list comps without putting \ line break.

Some other examples of list comprehensions

Example1: filter out Unicode values greater than 100.

lis2 = [ord(sym) for sym in symbols if ord(sym) > 100]
print(lis2)
>>>[101, 102, 103]

Example 2: Cartesian product

lis3 = [(student, subject) for student in students for subject in subjects]
print(lis3)
>>>[('jon', 'science'), ('jon', 'maths'), ('jon', 'history'), ('doe', 'science'), ('doe', 'maths'), ('doe', 'history'), ('jack', 'science'), ('jack', 'maths'), ('jack', 'history')]

Tuples and generator expressions

Generator expressions are similar to list comprehensions, but generator expression saves memory by yielding items one after the other instead of building a whole list to feed into the constructor.

tup1 = tuple(ord(sym) for sym in symbols)
print(tup1)
>>>(97, 98, 99, 100, 101, 102, 103)

Some of the introductory textbooks to python refer lists as mutable data types and tuples as immutable data types. But tuples are much more than that now let us look into areas where tuples can be used.

Tuple used as records

Tuples are widely used to store values as records,below given is an example of tuple used as record.

City = ("Tokyo", "Delhi", "New York")
Student = ("doe", "john", "jack")
student_list = [('john', 1), ("doe", 2), ('jack', 3)]

for student in student_list:
print('%s-%s' % student)
>>>john-1
doe-2
jack-3

Tuple unpacking

Extracting the values stored in a tuple is called tuple unpacking, there are many ways to unpack tuple values but parallel execution is one of the most efficient and easy way of tuple unpacking.

co_ordinates = (1.0, 2.0, 3.0)
x, y, z = co_ordinates
print(x, y, z)
>>>1.0 2.0 3.0

Another way of example of tuple example is unpacking is using *args in a function.

def div(a, b):
return a / b


t = (10, 2)
print(div(*t))
>>>5.0

Named tuples

Named tuples can be used as storage to store information about about an object.

In the below example a named tuple student is created for storing student information. and in the second line a student instance is created with name doe.

from collections import namedtuple

Student = namedtuple('Student', 'name marks')
doe = Student('Doe', (22, 34, 45, 64))
print(doe.marks)
>>>(22, 34, 45, 64)

Managing sequences with bisect and insort

collections.bisect has two methods bisect and insort for managing the sequences in order.

lis1 = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
print(bisect.bisect(lis1, 6))
bisect.insort(lis1, 31)
print(lis1)
>>>4
[1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30, 31]

In the above example bisect method will return the position of the element 6 in the list that will be 4.

The insort method will add the element into the correct position into the list that is the element 31 will be added to the end of the list.

Dictionaries

Dictionaries are the important not only in our programming implementation but in the whole python programming constructs. Dictionaries are used everywhere in classes,namespaces,modules constructs etc. Because of their crucial role hash tables are used in the back-end of dictionaries which make them very efficient.

Similar to list comprehensions that are used to create lists. Dict comprehensions are used to create dictionaries .

DIAL_CODES = [
(86, 'China'),
(91, 'India'),
(1, 'United States'),
(62, 'Indonesia'),
(55, 'Brazil'),
(92, 'Pakistan'),
(880, 'Bangladesh'),
(234, 'Nigeria'),
(7, 'Russia'),
(81, 'Japan'),
]
dict1 = {country: code for code, country in DIAL_CODES}
print(dict1)
>>>{'China': 86, 'India': 91, 'United States': 1, 'Indonesia': 62, 'Brazil': 55, 'Pakistan': 92, 'Bangladesh': 880, 'Nigeria': 234, 'Russia': 7, 'Japan': 81}

Handling missing key values in dict using default dict

While using dictionary there is a good chance of referring value that are not in the dictionaries, default dict is one type of dictionary that is used prevent this kind of problems.

dict2 = collections.defaultdict(list)
print(dict2[3])
>>>[]

Default dict takes a parameter known as default factory this value can be a list,dict,set etc. Based on this value if the key is not present in the dict the above value will be returned. So in the above example an empty list will be returned.

variations of dictionary

Ordered dict

maintains the keys in the insertion order. on calling the popitem method the first item will be popped by default. This can be changed by giving the parameter reverse=True with popitem().

Collections.counter

Counter is used to hold the integer count for each key on updating the values for the key counter will also be updated.

counter = collections.Counter('aaaabctdedede')
print(counter)
>>>Counter({'a': 4, 'd': 3, 'e': 3, 'b': 1, 'c': 1, 't': 1})counter.update('aaaaaa')
print(counter)
>>>Counter({'a': 10, 'd': 3, 'e': 3, 'b': 1, 'c': 1, 't': 1})

From the above example we can see that by updating the value of counter the count of a got updated in the dictionary.

Mapping proxy

In some cases we would not want to change the mappings of the dictionary in that case python provides a mappingproxy type whose mappings cannot be changed.

from types import MappingProxyType

d = {1: 'A'}
d_proxy = MappingProxyType(d)
print(d_proxy)

In the above example d_proxy is like an immutable dictionary whose assignment values cannot be changed.

d_proxy[1] = 'B'

Such a re-assignment is not possible.

Set theory

Now let us come to the last part of this article that is set theory, set is well defined collection of objects basic use is to avoid duplication.

Basic set operations

a = ['apple', 'orange', 'apple']
b = ['apple', 'apple']
a = set(a)
b = set(b)
print(a & b) # intersection of a & b
print(a | b) # Union of a and b
print(a - b) # Difference between a & b
>>>{'apple'}
>>>{'apple', 'orange'}
>>>{'orange'}

One important thing is that there is no literal definition for an empty set, empty set defined will be treated as a dictionary.

d1 = {'one'}
print(type(d1))
d2 = {}
print(type(d2))
>>><class 'set'>
>>><class 'dict'>
c = set() # empty set

Set comprehensions

Similar to dictionaries and lists set comprehension can be used for construction of set.

set1 = {chr(i) for i in range(1, 256)}
print(set1)

All Unicode representation for numbers 1 to 256.

--

--

krishnaprasad k
Nerd For Tech

Data engineer | Deep learning enthusiast | Back end developer |