Some Cool Python Code Snippets to Accelerate Your Python Knowledge

Sadman Kabir Soumik
Geek Culture
Published in
12 min readAug 20, 2021

--

Revisiting python fundamental concepts which include tips and tricks to make your code more pythonic.

All the code snippets below are using Python version 3.5+

Photo by Lukas Blazek on Unsplash

Combine two lists as a dictionary

keys = ['a', 'b', 'c']
values = [1, 2, 3]
dictionary = dict(zip(keys, values))
print(dictionary)
# output: {'a': 1, 'b': 2, 'c': 3}

Merge two dictionaries into one

x = {"a": 1, "b": 2}
y = {"b": 3, "c": 4}
z = {**x, **y}
print(z)
# output: {'a': 1, 'b': 3, 'c': 4}

Indexing strings

Print the last character of a string

a = "abcd"x1 = a[-1]      # last item in the array
x2 = a[-2:] # last two items in the array
x3 = a[:-2] # everything except the last two items
x4 = a[::-1] # all items in the array, reversed
x5 = a[1:3] # index 1,2 (excluding 3)
print(x1) # OUTPUT: d
print(x2) # OUTPUT: cd
print(x3) # OUTPUT: ab
print(x4) # OUTPUT: dcba
print(x5) # OUTPUT: bc

Appending vs Extending a Python List

Append one list to another

x = [1, 2, 3]
y = [4, 5]
x.append(y)
print(x)
# output: [1, 2, 3, [4, 5]]

Extend one list to another

x = [1, 2, 3]
y = [4, 5]
x.extend(y)
print(x)
# output: [1, 2, 3, 4, 5]

Add another item to a list

prog_language = ['Python', 'Java']
prog_language.append('Dart')
print(prog_language)
# output: ['Python', 'Java', 'Dart']

Merge two lists

num1 = [4, 5, 6]
num2 = [5, 6, 7]
result = num1 + num2
print(result)
# output: [4, 5, 6, 5, 6, 7]

Switch case in Python

Unlike every other programming language, Python does not have a switch or case statement. To get around this fact, we can use python’s dictionary mapping.

def numbers_to_strings(argument):
# argument: key of a dictionary
switcher = {
0: "zero",
1: "one",
2: "two",
}
return switcher.get(argument, "Data Not Available")
if __name__ == "__main__": result = numbers_to_strings(1)
print(result) # output: one

When the key is not available

def numbers_to_strings(argument):
switcher = {
0: "zero",
1: "one",
2: "two",
}
return switcher.get(argument, "Data Not Available")
if __name__ == "__main__": result = numbers_to_strings(4)
print(result)
# output: Data Not Available

Open text file

We can open a file like below:

file = open('filename.txt')

But when we open a file, we should also close that file after processing it. There are two ways to ensure a file is closed after opening it.

Method 1: using try-finally block

file = open('filename.txt')
try:
# do whatever you want to do with your file.
finally:
file.close()

Method 2: using with statement. with keyword before open takes care of closing a file properly.

with open('filename.txt') as my_file:
# do whatever you want to do with your file.

Use generators inside a function

x = sum(i for i in range(10))
print(x) # output: 45

Transpose a matrix

x = [[31, 17], [40, 51], [13, 12]]
print(list(zip(*x)))

The output of the above code

[(31, 40, 13), (17, 51, 12)]

Built-in functions of List

reverse()

language = ["Python", "Java", "Dart"]
language.reverse()
print(language)
# output: ['Dart', 'Java', 'Python']

insert()

x = [1, 2, 3, 4, 5, 6, 7, 8]
x.insert(0, 10) # insert 10, at position 0
print(x)
# output: [10, 1, 2, 3, 4, 5, 6, 7, 8]

count() | count the total number of presence of a certain item in a list

x = [1, 2, 3, 4, 1, 1]
print(x.count(1))
# output: 3

clear() | removes all items from a list

x = [1, 2, 3, 4, 1, 1]
x.clear()
print(x)
# output: []

index() | return the index of a certain element

x = ["a", "b", "c", "d", "e", "f"]
print(x.index("d"))
# output: 3

len() | return total length of a list

x = ["a", "b", "c", "d", "e", "f"]
print(len(x))
# output: 6

pop() | remove and return the last item of a list

x = ["a", "b", "c", "d", "e", "f"]print(x.pop())             # output: fprint(x)                   # output: ['a', 'b', 'c', 'd', 'e']

sort() | sort elements in a list

x = [2, 1, 3, 5, 4]
x.sort() # sort in ascending order
print(x) # output: [1, 2, 3, 4, 5]
y = [2, 1, 3, 5, 4]
y.sort(reverse=True) # sort in descending order
print(y) # output: [5, 4, 3, 2, 1]

remove() | remove a certain element from a list

x = [2, 1, 3, 5, 4, 3, 3]
x.remove(3) # remove the first occurrence of 3
print(x) # output: [2, 1, 5, 4, 3, 3]

Remove all occurrences of an item from a list

Method 1; using lambda function

# remove all 2 from the list a = [1, 2, 3, 2, 2, 2, 3, 4]
b = filter(lambda x: x != 2, a)
print(list(b))
# output: [1, 3, 3, 4]

Method 2; using the built-in filter

a = [1, 2, 3, 2, 2, 2, 3, 4]
b = filter((2).__ne__, a)
print(list(b))
# output: [1, 3, 3, 4]

Find min/max from a list of int/str

In case of List[int]

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]min_a = min(a)
max_a = max(a)
print(min_a) # OUTPUT: 1
print(max_a) # OUTPUT: 10

In the case of List[str]; based on lexicographical order

a = ["flower", "flow", "flights"]min_a = min(a)
max_a = max(a)
print(min_a) # OUTPUT: flights
print(max_a) # OUTPUT: flower

In the case of List[str]; based on string length

a = ["flower", "flow", "flights"]min_a = min(a, key=len)
max_a = max(a, key=len)
print(min_a) # OUTPUT: flow
print(max_a) # OUTPUT: flights

The difference among remove, del, pop

remove() | removes the first matching value, not a specific index

x = [2, 1, 4, 3]
x.remove(1)
print(x) output: [2, 4, 3]

del | removes the item at a specific index

x = [2, 1, 4, 3]
del x[0] # delete the item in index 0
print(x) # output: [1, 4, 3]

pop() | removes the item at a specific index and returns it

x = [2, 1, 4, 3]
print(x.pop(0)) # remove and return the item at index 0
# output: 2

Use
del to remove an element by index
pop() to remove it by index if you need the returned value
remove() to delete an element by value.

When to use: List vs Tuple vs Set

List

  • A strong culture among python communities is to store homogeneous data in the list. For example: lst= [1, 2, 3, 4, 5]
  • Mutable, which means you can always change a list after data assignment.
  • Common operations: append, extend, insert, remove, pop, reverse, count, copy, clear.

Tuple

  • A strong culture in python communities is using tuple to store heterogeneous data. For example: tup = (1, a, 3, d, X)
  • Immutable, which means you can’t change it after data assignment.
  • As you can’t add or remove items from it, there is no method available for a tuple to do such kinds of operations. Common operations in a tuple: count and index .

Set

  • A set is used to store unique values. It doesn’t allow any duplicate elements, whereas list and tuple allow duplicate elements. For example:
x = set(["foo", "bar", "baz", "foo", "qux"])print(type(x))             # output: <class 'set'>
print(x) # output: {'qux', 'baz', 'foo', 'bar'}

# another way to define set
x = {"foo", "bar", "baz", "foo", "qux"}
print(x)
# output: {'bar', 'foo', 'baz', 'qux'}
  • It is unordered whereas list and tuple are ordered.
  • A set itself may be modified, but the elements contained in the set must be of an immutable type. For example, you may include a tuple in a set.
x = {42, "foo", (1, 2, 3), 3.14159}print(x)         # output: {42, 3.14159, 'foo', (1, 2, 3)}

Common operations in set

union()

x = {"a", "b", "c", "d"}
y = {"b", "d", "a", "e"}
z1 = x | y
z2 = x.union(y)
print(z1) # output: {'d', 'e', 'c', 'b', 'a'}
print(z2) # output: {'d', 'e', 'c', 'b', 'a'}

Union and intersection over multiple sets

a = {1, 2, 3, 4}
b = {2, 3, 4, 5}
c = {3, 4, 5, 6}
d = {4, 5, 6, 7}
union = a.union(b, c, d)
intersection = a.intersection(b, c, d)
print(union) # output: {1, 2, 3, 4, 5, 6, 7}
print(intersection) # output: {4}

Check the memory usage

import sysa, b, c, d = "abcde", "xy", 2, 15.06
print(sys.getsizeof(a))
print(sys.getsizeof(b))
print(sys.getsizeof(c))
print(sys.getsizeof(d))

*args and **kwargs

*args

By using args, we can pass a variable number (as many as you want) of arguments to a function.

def sum_lists(*args):
return list(map(sum, zip(*args)))
a = [1, 2, 3]
b = [1, 2, 3]
c = [2, 3, 4]
result = sum_lists(a, b, c)
print(result)
# output: [4, 7, 10]

**kwargs

If we don’t know about the number of keyword arguments to pass as the parameter of a function. Then, we can use kwargs. It allows a variable number of named arguments in a function (similar to key:value pair).
Here is an example,

def get_move_info(**kwargs):
for key, value in kwargs.items():
print(f"{key} = {value}")
print()if __name__ == "__main__":# movie info 1get_move_info(
name="Interstellar",
release_year=2014,
director="Christopher Nolan")
# movie info 2
get_move_info(
name="The Machinist",
release_year=2004,
director="Brad Anderson",
lead_actor="Christian Bale")

Output

name = Interstellar
release_year = 2014
director = Christopher Nolan
name = The Machinist
release_year = 2004
director = Brad Anderson
lead_actor = Christian Bale

Here is another example,

def information(**data):
for key, value in data.items():
print(f"{key}: {value}")
print()
if __name__ == "__main__":information(
Firstname="Sadman",
Lastname="Soumik",
Age=26,
Phone=1234567890
)
information(
Firstname="John",
Lastname="Wood",
Email="johnwood@nomail.com",
Country="Wakanda",
Age=25,
Phone=9876543210,
)

Output

Firstname: Sadman
Lastname: Soumik
Age: 26
Phone: 1234567890
Firstname: John
Lastname: Wood
Email: johnwood@nomail.com
Country: Wakanda
Age: 25
Phone: 9876543210

Check if a file exists

import osif os.path.isfile(filepath):       # filepath = location of the file
print("File exists")

Check if a directory exists, if not, create the directory

SAVE_DIR = "target_dir"  
if not os.path.exists(SAVE_DIR):
os.makedirs(SAVE_DIR)

Lambda, Map, and Filter

lambda

  • Lambda functions are known as anonymous functions in Python. These kinds of functions are declared without any name.
  • Can accept any number of arguments.
  • Restricted to only a single expression.
  • Used only one-time.
  • The Lambda function is used when you need a function for a short period of time.
multiply = lambda x, y: x * y
print(multiply(2, 2)) # output: 4
multiply = lambda x, y, z: x * y * z
print(multiply(2, 2, 2)) # output: 8

map

# basic syntax
map(function_object, iterable_1, iterable_2, ...)

the map takes a function object, and iterables (e.g. )

# a function that adds 10 with every number
def add_ten(x):
return x + 10
x = [1, 2, 3, 4]
ans = map(add_ten, x)
print(list(ans))
# OUTPUT: [11, 12, 13, 14]

filter

It works similar way like a map. The difference is it makes a new list from the element in the list that satisfy some condition. In the case of parameters, it takes a function and one iterable.
Basic syntax:

filter (function, iterable)

The following code does nothing on seq as the lambda function does not hold any condition.

seq = [1, 2, 3, 4]
result = filter(lambda x: x + 1, seq)
print(list(result))
# OUTPUT: [1, 2, 3, 4]

filter only works on condition, so we need to give some conditional statement with lambda.

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))
# OUTPUT: [2, 4, 6, 8]

The above code can be written as below without the lambda function

def even_numbers(num):
# return the numbers which are only divisible by 2
return num % 2 == 0
db = [1, 2, 3, 4, 5, 6, 7, 8, 9]
even_numbers = filter(even_numbers, db)
print(list(even_numbers))
# OUTPUT: [2, 4, 6, 8]

Collections module

Count distinct elements in a list

from collections import Counter

words = ["a", "b", "c", "a", "b", "a"]

print(dict(Counter(words)))
# {'a': 3, 'b': 2, 'c': 1}
print(list(Counter(words).keys()))
# ['a', 'b', 'c']
print(list(Counter(words).values()))
# [3, 2, 1]

Find the most frequent element in a list

from collections import Counter


def most_frequent(lst):
data = Counter(lst)
return data.most_common(1) # returns most frequent 1 element


list = [2, 1, 2, 2, 1, 3, 3, 3, 2]
print(most_frequent(list))

# output: [(2, 4)] # means, 2 is the most frequent element which appears 4 times.

Another example:

from collections import Counter


def most_frequent(lst):
data = Counter(lst)
return data.most_common(1)[0][0]
# [0][0] is the first element of a matrix

list = [2, 1, 2, 2, 1, 3, 3, 3, 2]
print(most_frequent(list))
# output: 2

Creating class using namedtuple

Though most of us are familiar with the naive way of creating classes and objects like below:

class Transaction:
def __init__(self, amount, sender, receiver, date):
self.amount = amount
self.sender = sender
self.receiver = receiver
self.date = date
trnsaction_1 = Transaction(100, "Alice", "Bob", "2019-01-01")
print(trnsaction_1.receiver)
# output: Bob

But we can create the same thing way easier way if the objects are immutable, then with namedtuple from the collections module.

from collections import namedtupleTransaction = namedtuple('Transaction', ["amount", "sender", "receiver", "date"])transaction_1 = Transaction(amount=100, sender="Alice", receiver="Bob", date="2019-01-01")print(transaction_1.receiver)
# output: Bob

We can also print the above information in a dictionary format:

print(transaction_1._asdict())# output: {'amount': 100, 'sender': 'Alice', 'receiver': 'Bob', 'date': '01/01/2019'}

Create dictionaries using defaultdict from collections module.

from collections import defaultdict

employee_record = [
("Kabir", "ML", "level-b"),
("Sunehra", "SDE", "level-b"),
("Smith", "ML", "level-c"),
("William", "HR", "level-c"),
]

employee_name_by_dept = defaultdict(list)

for name, dept, level in employee_record:
employee_name_by_dept[dept].append(name) # dept as key, name as values

print(dict(employee_name_by_dept))
#output: {'ML': ['Kabir', 'Smith'], 'SDE': ['Sunehra'], 'HR': ['William']}

deque from collections module

from collections import deque


employee_list = ["Soumik", "Jamie", "Smith"]
employee_list_deque = deque(employee_list)

# O(1) time performance
employee_list_deque.appendleft("Sunehra")
print(list(employee_list_deque))
# output: ['Sunehra', 'Soumik', 'Jamie', 'Smith']

Although deque adds entries to the beginning of a sequence more efficiently than a list, deque does not perform all of its operations more efficiently than a list. For example, accessing a random item in a deque has O(n) performance, but accessing a random item in a list has O(1) performance.

Use deque when it is important to insert or remove elements from either side of your collection quickly.

Creating a list of dictionaries from multiple dictionaries

from collections import ChainMap

salary = {"SDE": 100000, "HR": 80000, "MTO": 60000}
office_hq = {"Asia": "Singapore", "Europe": "Dublin", "North America": "USA"}
age_limit = {"SDE": 40, "HR": 50}

employee_info = ChainMap(salary, office_hq, age_limit)
print(employee_info.maps)

Output:

[{'SDE': 100000, 'HR': 80000, 'MTO': 60000}, {'Asia': 'Singapore', 'Europe': 'Dublin', 'North America': 'USA'}, {'SDE': 40, 'HR': 50}]

Create ordered dictionary using OrderedDict

import collections

# remembers the order
d = collections.OrderedDict()
d["A"] = 65
d["C"] = 67
d["B"] = 66
d["D"] = 68

for key, value in d.items():
print(key, value)

output:

A 65
C 67
B 66
D 68

Object-Oriented Programming concepts

Creating class in Python

class Transaction:    def __init__(self, sender, recipient, amount):
self.sender = sender
self.recipient = recipient
self.amount = amount
def __str__(self):
return f"{self.sender} -> {self.recipient} : {self.amount}"

if __name__ == "__main__":
transaction_1 = Transaction("Alice", "Bob", 100)
print(transaction_1)

output:

Alice -> Bob : 100

Inheritance in Python

Define a base/parent class:

class Employee:    def __init__(self, name, salary):
self.name = name
self.salary = salary
def __str__(self):
return f"{self.name} earns {self.salary}"

if __name__ == "__main__":
e1 = Employee("John", 100)
print(e1)

outputs:

John earns 100

Now we will define another class superclass/child class that extends the base class Employee

class Employee:    def __init__(self, name, salary):
self.name = name
self.salary = salary
def __str__(self):
return f"{self.name} earns {self.salary}"

class Manager(Employee):
def __init__(self, name, salary, bonus):
super().__init__(name, salary)
self.bonus = bonus
def __str__(self):
return f"{self.name} earns {self.salary} and gets {self.bonus} bonus"

if __name__ == "__main__":
e1 = Employee("John", 100)
e2 = Manager("John", 100, 10)
print(e2)

output:

John earns 100 and gets 10 bonus

Polymorphism in Python

Polymorphism means more than one form, the same object performing different operations according to the requirement.

Polymorphism can be achieved by using two ways, those are

  1. Method overriding
  2. Method overloading

Method overloading means writing two or more methods in the same class by using same method name, but the passing parameters is different.

Method overriding means we use the method names in the different classes, which means parent class method is used in the child class.

Method Overloading in Python

When people do method overloading in languages like Java, they generally want a default value (if they don’t, they generally want a method with different parameters). In Python, we don’t do things that way. So, in Python, we can assign default values like the below:

class Employee:    def __init__(self, name, salary):
self.name = name
self.salary = salary
def full_name(self, first_name=None, last_name=None):
if first_name and last_name:
return f"{first_name} {last_name}"
else:
return f"{self.name}"
if __name__ == "__main__":
employee = Employee("John", 10000)
print(employee.full_name())
print(employee.full_name("John", "Doe"))

Output:

John
John Doe

Method Overriding in Python

class Dog:
def bark(self):
print("WOOF")

class BobyDog(Dog):
def bark(self):
print("WoOoOoF!")
if __name__ == "__main__":
big_dog = Dog()
big_dog.bark()
baby_dog = BobyDog()
baby_dog.bark()

output

WOOF
WoOoOoF!

Encapsulation in Python

The process of wrapping up variables and methods into a single entity is known as Encapsulation. It is one of the underlying concepts in object-oriented programming (OOP). It acts as a protective shield that puts restrictions on accessing variables and methods directly and can prevent accidental or unauthorized modification of data. We can implement encapsulation in the following way:

class Human:    def __init__(self):
self.__var = "private variable"
self.var = "public variable"
def print_var(self):
# we can access the private variable in the class
print(self.__var)
if __name__ == "__main__":
h = Human()
h.print_var() # prints "private variable"

print(h.var) # prints "public variable"

# private variable cannot be accessed outside the class
print(h.__var) # does not work, will give error

Author: Sadman Kabir Soumik
LinkedIn: sksoumik

--

--

Sadman Kabir Soumik
Geek Culture

Artificial Intelligence | Cloud Computing | Back-End Engineering ☕️☕️