Python is cool, no doubt about it. But, there are some angles in Python that are even cooler than the usual Python stuff.

Here you can find 100 Python tips and tricks carefully curated for you. There is probably something to impress almost anyone reading it.

This is more like a Python Tricks Course that you can benefit from at various levels of difficulty and creativity. 

Holy Python is reader-supported. When you buy through links on our site, we may earn an affiliate commission.

So, you might want to pace yourself to avoid burnout, skim it as you wish or go through each point if you’re a beginner. 

You can also blend it with your #100daycoding #100daywithPython routines.

Tips are divided in 3 sections, this should make navigation a bit easier.: 

  • Beginner
  • Intermediate
  • Advanced


Estimated Time


Skill Level


Content Sections



Who Is It For?

If you took a Python course these somewhat niche methods might have escaped the curriculum. Or if you’re switching to Python from another language you might not have heard of these unique approaches even as a seasoned programmer.

Here is a webpage of Python finesse in 100 points that are guaranteed to step up your Python game at least in some way and expand your creative horizons.

These Python tricks are aimed at a programmer audience at varying levels. Here are some ideas who might benefit from the list:

  • If you took a Python 3 course lately
  • If you recently learned Python
  • If you are still learning Python and got the basics under control
  • If you are an experienced programmer but switching to Python for the first time
  • If you are curious about some interesting and unique ways you can code in Python
  • If you are an advanced user but still suspecting you might benefit from some tricks you might have missed

Feel free to digest in chunks, combine with your #100dayPython routine, make a quick skim, make it a quarantine goal (this article is written in 2020) or completely have it your way.

Here are 100 Python Tips and Tricks:

Beginner Level

If you are dedicated to learning Python and creating great things in the future with it. This list will offer you a great push to cover some of the topics that can go unnoticed or not be included in the conventional Python lessons.

The list includes a few well known Python concepts as well as lots of lesser known tricks and even touches on computer science a little bit in the next session.

We hope you enjoy the full list and if you have time share the love on social media.

Let’s start with beginner Python tips!

1) print(\a): (Make print sing)

Okay, technically not singing but can you believe printing \a creates a Windows chime?

This is because \a is reserved to warning notification sound in Windows and printing it in Python triggers it.

You can check out this post to see an alarm clock made by Python’s print function only.

import antigravity

2) Dictionary Merge: (Python Syntax Show Off)

Here is a fantastic Python approach. Do you have 2 dictionaries that you’d like to merge easily? You can use ** notation for **kwargs-like objects (values with names like dictionaries) to merge them conveninently.

Let’s say you have 2 Olympics results from 2 separate countries that held the events. Dictionary 1 named: China_olympics and then Japan_olympics and you’d like to make a shallow merge. All you have to do is:

{**China_olympics, **Japan_olympics}

Python will take care of the rest, making it a breeze.

Here is a demonstration:

d1={"A": 10, "B": 20, "C": 30}
d2={"X": 100, "Y": 200, "Z": 300}

d3={**d1, **d2}
{'A': 10, 'B': 20, 'C': 30, 'X': 100, 'Y': 200, 'Z': 300}

3) Proper File Paths: (Handling Paths)


This one is a life saver. standing for raw string, r in front of the string quotes ensure that file paths don’t get confused between Python and system settings.

Whenever you’re typing paths in your code, just by including that r in front of the quotes you can avoid lots of errors that might occur due to conflicts and confusions regarding path symbols like: /, //,  \. This problem occurs more often than you’d imagine and it can be very frustrating to troubleshoot. Just use r in front and path problems no more!

See demonstration below:

Python file path trick (using r letter)

Also, in some cases you might need to use double back slashes instead of forward slashes. This is because different systems use different path structures. When working with a script that communicates with Windows OS for example, you’ll need to use “\\

4) Big Number Readability: (Millions and Billions)

you can separate zeros with underscore (_)

This one is a potential favorite for teachers, scientists, finance quants, accountants, quantum physicists, actuaries, traders and all the rest of the big number people.

Underscore _  can be used to separate zeros in Python and this will make big numbers more readable while mathematically it won’t affect the syntax so you can still carry out arithmetic operations as normal:

This makes big numbers way more readable when needed.

print(1_000_000 +1)

5) Let the code draw: (Python Turtle Drawing)


it’s worth mentioning in case you might have missed it. Turtle is a drawing library that works with Python codes. Creating patterns with turtle can be super intuitive in learning Python.

We have some extensive tutorials that are guaranteed to step up your Python skills especially regarding programming fundamentals. Here are a couple of articles to check:

The ultimate Python Turtle Tutorial for learning main Python concepts.

Drawing spirals with Python’s Turtle library

6) Chain Operators: (Larger Than and Smaller Than)

You can chain comparison operators in Python as following:

n = 10
result = 1 < n < 20

distance = 100
checker = 50 < distance < 250


7) Pretty Print: (Pprint)

print function of Python has some pretty cool features already. But sometimes you might need something just a bit more powerful. pprint offers some structured printing opportunities when your data is more structured and nested (as it occurs with most web queries, web crawling, database results etc.)

Here is an example:

(data is taken from a geopy result as demonstrated in #74 in this article.)

data = {'place_id': 259174015, 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0.', 
        'osm_type': 'way', 'osm_id': 12316939, 'boundingbox': ['42.983431438214', '42.983531438214', '-78.706880444495', 
        '-78.706780444495'], 'lat': '42.983481438214326', 'lon': '-78.70683044449504', 'display_name': '''230, Fifth Avenue,
        Sheridan Meadows, Amherst Town, Erie County, New York, 14221, United States of America''', 
        'class': 'place', 'type': 'house', 'importance': 0.511}

pprint.pprint(data, indent=3)
{  'boundingbox': [  '42.983431438214',
'class': 'place',
'display_name': '230, Fifth Avenue,\n'
' Sheridan Meadows, Amherst Town, Erie County, New '
'York, 14221, United States of America',
'importance': 0.511,
'lat': '42.983481438214326',
'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
'lon': '-78.70683044449504',
'osm_id': 12316939,
'osm_type': 'way',
'place_id': 259174015,
'type': 'house'}

8) Getting rid of unwanted characters: (left strip, right strip and just strip)

You can get rid of whitespaces or any specific character using strip methods in Python. You can use either plain strip for both sides, lstrip for the left side and rstrip for the right side only.

str="+++World Cup+++"

World Cup

9) Merging strings: (join method)

You can use join method to combine strings. Very useful indeed.

lst="Nepal, Bhutan, Korea, Vietnam"

Nepal, Bhutan, Korea, Vietnam

10) Versatile Arithmetic Operators: (Multiply Lists & Add Strings)

Everybody can do arithmetic with numbers but Python can do arithmetics with non-numbers too.

You can add strings and lists with arithmetic operator + in Python.

asd + asd

= asdasd

str2=" there"

hey there

11) Floor Division: (Keep the change)

When we speak of division we normally mean (/) float division operator, this will give a precise result in float format with decimals.

For a rounded integer result there is (//) floor division operator in Python. Floor division will only give integer results that are round numbers.

print(1000 // 400)
print(1000 / 400)
Coins to demonstrate Python floor division

12) Negative Indexing: (Accessing from the end)

In Python you can use negative indexing. While positive index starts with 0, negative index starts with -1.

Here is a demo:
(last one is from index -1 to -4 with steps of -1), see below for more information.


If you’re confused about this format or negative indexing as well as Python slice notation with negative steps here are 2 great resources to learn and practice.

Python Slice Notations

Python Slice Notation Exercises


13) Break up strings: (Split Method)

Split function is a must know from the early on. Whether it’s data science or website development or database applications or just simple Python practicing, split function is one powerful function and it makes working with strings so much easier.

Its use is simple:

str = "Hello World"
a = str.split(" ")

print (a)
["Hello", "World"]

14) When the code is too fast: (Make Python Sleep)

Sometimes you want your code to execute slowly. You might want to demonstrate something or there might be steps that require little breaks. sleep method of time library is perfect for that.

Make secs any integer representing seconds:

import time

15) Reverse data: (Slice Notation)

8- Reversing through slicing



16) Reverse data: (Reversed Function & Reverse Method)

Reversed function and reverse method can only be used to reverse objects in Python. But there is a major difference between the two:

  • reversed function can reverse and iterable object and returns a reversed object as data type.
  • reverse method can only be used with lists as its a list method only.

Check out 3 examples below:




['water', 'wind', 'fire', 'earth']




<reversed object at 0x000001C247364C88>
['water', 'wind', 'fire', 'earth']




17) Multi Assignments: (One-Liner)

This one is self explanatory but still good to be aware of:

a = [1000, 2000, 3000]
x, y, z = a


18) Code Sections: (Spyder)

6- #%% Creating Code Sections in your IDE (Spyder)

Are you coding in Spyder? Use this command to create subsections in your code and you can run each section with Ctrl+Enter.

This trick almost converts your Spyder IDE to a Notebook, very cool trick for practicing, experimenting and learning or teaching purposes.

If you’d like to install Spyder a free open source Python IDE that we recommend, it comes with Anaconda click here to see how to install Anaconda.

See demonstration below:

Creating code sections in Spyder with (#%%)

19) Remove Duplicates: (set function)

Most straightforward approach to removing duplicates in a list is probably using the set() function.

Set in Python is a datatype that’s sort of between lists and dictionaries.

It takes unique values only, it’s mutable and like dictionaries it’s unordered. Here is an example:


{1, 2, 3, 4, 5, 6, 7}

The new object will have a “set” type.

<class 'set'>

If you want to overcome the type conversion and keep your data as a list just add a list function as below and it will stay as a list after set function removes all the duplicates:



<class 'list'>

20) Python Working Directory: (os.getcwd())

2- This one is so helpful when needed. Sometimes you may need to identify or double check where your Python is working (directory wise)

get working directory with getcwd() method of os library:

import os
dirpath = os.getcwd()

This information can be important sometimes when you’re coding and dealing with data and/or files etc.

For instance: you can use only file names to work with files in your working directory instead of their full file path names.

20) Python Working Directory: (os.chdir())

So what if you’re not happy with the current working directory?  Don’t worry, you can use the same Python library named os to change the working directory.

change working directory with chdir() method of os library:

ps(don’t forget to use r letter in front of your path to avoid path notion conflicts.)

import os 


22) Printing libraries: (To get their directiories)

73- print a library

Have you ever tried printing a library name directly in Python? What will happen is, it will tell you the location where library file is located. Pretty cool and such a Python feature.

import pandas
<module 'pandas' from 'C:\\Anaconda3\\lib\\site-packages\\pandas\\'>

23) Membership Operators: (in & not in)

Makes it very convenient to find out if a subgroup exists in a data object

example with in

lst = "10, 50, 100, 500, 1000, 5000"
for i in lst:
    if i == str(0):
        print(i, end="|")

example with not in

lst = list(range(100))

if 500 not in lst:
    print("Value is out of range")
Value is out of range

24) Advanced Print: (sep parameter)

Do you want to print multiple values with a user-defined separater? You can use print’s sep parameter for that.


print(str1, str2,sep="@")

25) Advanced Print: (end parameter)

Python’s print function has a \n new line character at the end by default.

But, sometimes, you just don’t want it to enter a new line after print or better yet you might want to add a different character to the end of each print function.

end= parameter is perfect for that. Here is an example:

print("one" , end ="," )
print("two", end =",")
one, two, three

26) Triple quotes: (Multiline Strings)

”’some text here”’

Triple quotes are a solution to a common complication when working with strings.

Python will let you create multi-line strings as long as you use triple quotation marks, it works with both single quotes and  double quotes as long as you use 3 of them.

Here is a simple example:

a = """Here is a nice quote from George Orwell's 1984:
Under the spreading chestnut tree I sold you and you sold me:
There lie they, and here lie we Under the spreading chestnut 


27) List Comprehension: ()

List comprehension is a very cool way to build lists in 1 line.

You can include conditional statements, lambda, functions, loops all in 1 line of list comprehension code. No wonder why it’s praised so much.

Try these list comprehension exercises and you’ll see how useful and addictive they can be.

28) Dict Comprehension: ()

Dict comprehension is lesser known than list comprehension but that doesn’t mean it’s less impressive. You can build dictionaries from almost any structure and manipulate different combinations of dictionary keys and values with this Python structure.

Here are some dict comprehension exercises as well in case you’d like to practice them.

29) Partial assignments: (List Unpacking)

Do you want to assign one or more elements of a list specifically and assign all the remains to something else? Easy with Python.

Check out this syntax that makes use of unpacking notation in Python:

lst = [10, 20, 30, 40]
a, *b = lst

Here is another example, basically variable with the star (*) gets assigned to the leftovers.

lst = ["yellow", "gray", "blue", "pink", "brown"]
a, *b, c = lst

["gray", "blue", "pink"]

30) Ordered Dictionaries: (from collections)

Python’s default dictionary data structure doesn’t have any index order. You can think of key-value pairs as mixed items in a bag. This makes dictionaries very efficient to work with. However, sometimes you just need your dictionary to be ordered.

No worries, Python’s collections library has a module named OrderedDict that does just that.

import collections

d = collections.OrderedDict()
d[1] = 100
d[2] = 200

OrderedDict([(1, 100), (2, 200)])

31) Permutations: (from itertools)

Whether it’s betting with your friends, calculating a sophisticated mathematical equation, reading Adam Fawer’s Improbable or evaluating your chances before a Vegas trip; you never know when you might need a couple of permutation calculations.

Thanks to Python you don’t have to go through the tedious arithmetics of permutations and you can get it done with a simple piece of code.

Check out this making use of permutations method from itertools library:

First print shows to total amount of different probabilities, second print demonstrates all the possible events.

import itertools

lst = [1,2,3,4,5]

for i in itertools.permutations(lst):
    print (i, end="\n")


(1, 2, 3, 4, 5)
(1, 2, 3, 5, 4)
(1, 2, 4, 3, 5)
(1, 2, 4, 5, 3)
(1, 2, 5, 3, 4)
(1, 2, 5, 4, 3)
(1, 3, 2, 4, 5)
(1, 3, 2, 5, 4)
(1, 3, 4, 2, 5)
(1, 3, 4, 5, 2)
(1, 3, 5, 2, 4)
(1, 3, 5, 4, 2)
(1, 4, 2, 3, 5)
(1, 4, 2, 5, 3)
(1, 4, 3, 2, 5)
(1, 4, 3, 5, 2)
(1, 4, 5, 2, 3)
(1, 4, 5, 3, 2)
(1, 5, 2, 3, 4)
(1, 5, 2, 4, 3)
(1, 5, 3, 2, 4)
(1, 5, 3, 4, 2)
(1, 5, 4, 2, 3)
(1, 5, 4, 3, 2)
(2, 1, 3, 4, 5)
(2, 1, 3, 5, 4)
(2, 1, 4, 3, 5)
(2, 1, 4, 5, 3)
(2, 1, 5, 3, 4)
(2, 1, 5, 4, 3)
(2, 3, 1, 4, 5)
(2, 3, 1, 5, 4)
(2, 3, 4, 1, 5)
(2, 3, 4, 5, 1)
(2, 3, 5, 1, 4)
(2, 3, 5, 4, 1)
(2, 4, 1, 3, 5)
(2, 4, 1, 5, 3)
(2, 4, 3, 1, 5)
(2, 4, 3, 5, 1)
(2, 4, 5, 1, 3)
(2, 4, 5, 3, 1)
(2, 5, 1, 3, 4)
(2, 5, 1, 4, 3)
(2, 5, 3, 1, 4)
(2, 5, 3, 4, 1)
(2, 5, 4, 1, 3)
(2, 5, 4, 3, 1)
(3, 1, 2, 4, 5)
(3, 1, 2, 5, 4)
(3, 1, 4, 2, 5)
(3, 1, 4, 5, 2)
(3, 1, 5, 2, 4)
(3, 1, 5, 4, 2)
(3, 2, 1, 4, 5)
(3, 2, 1, 5, 4)
(3, 2, 4, 1, 5)
(3, 2, 4, 5, 1)
(3, 2, 5, 1, 4)
(3, 2, 5, 4, 1)
(3, 4, 1, 2, 5)
(3, 4, 1, 5, 2)
(3, 4, 2, 1, 5)
(3, 4, 2, 5, 1)
(3, 4, 5, 1, 2)
(3, 4, 5, 2, 1)
(3, 5, 1, 2, 4)
(3, 5, 1, 4, 2)
(3, 5, 2, 1, 4)
(3, 5, 2, 4, 1)
(3, 5, 4, 1, 2)
(3, 5, 4, 2, 1)
(4, 1, 2, 3, 5)
(4, 1, 2, 5, 3)
(4, 1, 3, 2, 5)
(4, 1, 3, 5, 2)
(4, 1, 5, 2, 3)
(4, 1, 5, 3, 2)
(4, 2, 1, 3, 5)
(4, 2, 1, 5, 3)
(4, 2, 3, 1, 5)
(4, 2, 3, 5, 1)
(4, 2, 5, 1, 3)
(4, 2, 5, 3, 1)
(4, 3, 1, 2, 5)
(4, 3, 1, 5, 2)
(4, 3, 2, 1, 5)
(4, 3, 2, 5, 1)
(4, 3, 5, 1, 2)
(4, 3, 5, 2, 1)
(4, 5, 1, 2, 3)
(4, 5, 1, 3, 2)
(4, 5, 2, 1, 3)
(4, 5, 2, 3, 1)
(4, 5, 3, 1, 2)
(4, 5, 3, 2, 1)
(5, 1, 2, 3, 4)
(5, 1, 2, 4, 3)
(5, 1, 3, 2, 4)
(5, 1, 3, 4, 2)
(5, 1, 4, 2, 3)
(5, 1, 4, 3, 2)
(5, 2, 1, 3, 4)
(5, 2, 1, 4, 3)
(5, 2, 3, 1, 4)
(5, 2, 3, 4, 1)
(5, 2, 4, 1, 3)
(5, 2, 4, 3, 1)
(5, 3, 1, 2, 4)
(5, 3, 1, 4, 2)
(5, 3, 2, 1, 4)
(5, 3, 2, 4, 1)
(5, 3, 4, 1, 2)
(5, 3, 4, 2, 1)
(5, 4, 1, 2, 3)
(5, 4, 1, 3, 2)
(5, 4, 2, 1, 3)
(5, 4, 2, 3, 1)
(5, 4, 3, 1, 2)
(5, 4, 3, 2, 1)

Here is a little twist if you’d like to see all the different numbers that are possible to generate with those 5 integers:

import itertools

lst = [1,2,3,4,5]
for i in itertools.permutations(lst):
    print (''.join(str(j) for j in i), end="|")


You can see all the other cool modules from itertools library on this Official Python page of itertools.

32) Factorial: (user function)

How about factors of a number? This can easily be achieved by using the % modulus operator of Python.

In a range from 1 up to the number we’re searching factors for, if any number can divide the main number without any remainders, that means its a factor of our number. Here is the idea in code:


n = 159

for i in range(1, n + 1):
    if f % i == 0:

33) clear console: (Spyder)

This one is for Spyder users but you can imagine there is a command to clear all IDE consoles.

Simply type clear on the console and your console will be cleared.

Note: type clear in the console (where you get outputs, or values get printed) instead of where you code (the editor).

34) N largest & N smallest: (Standard heapq library)

Sometimes max and min functions might not cut it for you when you need multiple max or multiple min values from a set of values.

Check out heapq library that makes getting n largest or n smallest values much easier than usual techniques:

It works with the floats too

import heapq

grades = [5, 78, 6, 30, 91, 1005.2, 741, 1.9, 112, 809.5]
print(heapq.nlargest(2, grades))
print(heapq.nsmallest(5, grades))
[1005.2, 809.5]
[1.9, 5, 6, 30, 78]

35) Make it immutable: (frozenset)

frozenset() function allows lists to be immutable.

On some occasions you might have started your program with a list instead of tuples because of the conclusion that mutable data structure is more suitable for the project. But things change, projects evolve and ideas are known to change route. Now you decide that you needed immutable structure but it seems to late to undertake the tedious work of converting your lists? No worries. frozenset() will make it a breeze.

lst = ["June", "July", "August"]

['May', 'July', 'August']

i_lst[0] = "June"
TypeError: 'frozenset' object does not support item assignment

Bonus) Short library names: (import as)

Libraries are Python’s strong suit. Whether it’s external libraries or default libraries there is so much to discover and make use of.

That also means they come with all sorts of names. When you’re using a library frequently in a code it can get tedious to type the full name while using library’s methods.

To help with that you can import libraries as with a more convenient name. Here are some examples:

import matplotlib as mpl
import pandas as pd
import numpy as np
import statsmodels as sm
import tensorflow as tf
import seaborn as sb

Intermediate Level

The list continues with slightly more complex Python concepts, tips and tricks.

36) A beautiful counter: (itertools / count)

count method from itertools is kind of a smart counter which will automatically update itself inside the same kernel.

Check out how it counts in this mini example:

from itertools import count

index = count()

You can also put it inside a loop like this:

from itertools import count

c = count()

for i in range(20):
    print(next(c), end="|")

37) A different kind of counter: (collections / counter)

Counter method from Collections library will count inside your data structures in a sophisticated approach. It will return a dictionary of the results.

It’s probably the one liner approach as far as counters go.

from collections import Counter

counter = Counter(['red', 'red', 'red', 'blue', 'yellow'])
Counter({'red': 3, 'blue': 1, 'yellow': 1})

There is more to collections’ counter.

If you pass values as a parameter it will actually form the dictionary for you. You can even construct lists from the counter in a smart way.

Check out this example:

from collections import Counter

counter = Counter(red=1, blue=3, yellow=2)
Counter({'blue': 3, 'yellow': 2, 'red': 1})
['red', 'blue', 'yellow']
{'red': 1, 'blue': 3, 'yellow': 2}

38) Extracting nested data: (itertools)

You can also flatten nested data using chain method from itertools.

import itertools

a = [[1, 2, 3], [4, 5], [6]]
for i in (itertools.chain.from_iterable(a)):
[1, 2, 3, 4, 5, 6]

39) Unpacking: (star notation method)

You can unpack collections with 1 star notation: *

You can unpack named collections with 2 star notation: **

So, if a function takes iterables as argument then you can pass iterables with star notation to such functions.

Here are some examples:

a = [1,1,1,2,3,75,4,5,6]

import itertools

def lister(*x):
    for i in x:
        print(i, end="|")

a = [1,1,1,2,3,75,4,5,6]

40) For loop + else: (for else)

For else construction confuses even the most seasoned Python programmers sometimes. But it’s actually not that complicated at all.

Else clause is executed after for loop completes. It can be difficult to know if the loop successfully completed especially if there is a break statement in the loop. Else statement here assures us that loop ran successfully throughout.

for i in range(5):

So it seems redundant hence the confusion but see it this way. What if there was a break statement in the loop:

for i in range(5):
    if i == 2:

Else clause in For Else structures are completion clauses. They are confused heavily because they resemble if / else structures where else triggers a conditional behavior rather than a completion behavior. This could probably be avoided with a slight twist like calling it else finish or something, but alright. Let’s love Python with its tiny imperfection and not forget the insane benefits it brings to the table. 🙂

41) Swapping Dictionary Key & Values: (zip method)

So, how hard is reversing values and keys in a dictionary? Not hard at all, not in Python at least.

Here  are some really sleek ways to manipulate Python dictionaries that makes one fall in love with Python once again.

Here is an example:

a = {1:11, 2:22, 3:33}

b = zip(a.values(), a.keys())
c = dict(b)

{11: 1, 22: 2, 33: 3}

Here it is in a shortened version:

a = {1:11, 2:22, 3:33}
b = dict(zip(a.values(), a.keys()))

{11: 1, 22: 2, 33: 3}

42) Swapping Dictionary Key & Values: (dict comprehension method)

Dictionary Comprehension is a great way to achieve some dictionary operations, here is a great example:

a = {1:11, 2:22, 3:33}

b = (a.items())
c = {i:j for j,i in b}

{11: 1, 22: 2, 33: 3}

Or the same thing in a shorter way:

a = {1:11, 2:22, 3:33}

b = {i:j for j,i in a.items()}

{11: 1, 22: 2, 33: 3}

43) Conditional Statements: (One-Liner)

One liners are a sweet aspect of Python and can be applied to many concepts.

(Also known as ternary operator or casually if-else statement)


c = True if a**2 > 100 else False

44) Lambda: (One-Liner)

Lambda is like a user-defined one line mini function. When you have a function that’s not too complicated and that can be done as a lambda it just makes it much more convenient to type it in 1 simple line. Makes you realize how much Python is practicality oriented.

Lambda syntax can take some getting used to but we have great interactive lambda exercises to help you get moving.

Lambda is very useful for defining mini functions in 1 line:

a = lambda x: x**2

45) Returning multiple values: (return statement)

You can have a python function return multiple values.

(Not to be confused with multiple return statements which is not possible as return statement terminates a function in Python.)

def loc_id(city, county, state):
    return city, county, state

a = loc_id("LA", "OC", "FL")

("LA", "OC", "FL")

46) Function return assignments: (One-Liner)

One liners are huge in Python, which makes the syntax so attractive and practical sometimes. You can also assign values to multiple variables in one line:

def loc_id(city, county, state):
    return city, county, state

a,b,c = loc_id("LA", "OC", "FL")


47) Anagram Checker: (sorted function)

A simple way to approach this is to use Python’s sorted function. If 2 words are anagrams they should be the same when both are sorted alphabetically.
def anagram_checker(str1, str2):
    return sorted(str1) == sorted(str2)

print(anagram_checker('vases', 'saves'))
print(anagram_checker('cola', 'coal'))
print(anagram_checker('cake', 'take'))

48) Anagram Checker: (Counter)

We just saw counter method. Here is a creative application of it. Counter method of collections library can also be ideal for this task.

What collections.counter does is, it will return a subclass of dict object which has each element as a key and their counts as the value.

from collections import Counter 
def anagram_checker(str1, str2): 
    return Counter(str1) == Counter(str2)

print(anagram_checker('senator', 'treason'))
print(anagram_checker('section', 'notice'))
print(anagram_checker('relation', 'oriental'))

49) Enumerate: (Enumerated Iterables)

When you need to add counters to an iterable, enumerate is usually the most elegant approach. It will return the iterable (say list, tuple, range, string or dictionary etc.) with the counters and returned object will be an enumerate.

[(0, 'W'), (1, 'h'), (2, 'a'), (3, 't'), (4, 's'), (5, 'u'), (6, 'p')]

You can also tell enumerate what number to start from:

str=["sun", "moon", "mars", "venus"]
[(100, 'sun'), (101, 'moon'), (102, 'mars'), (103, 'venus')]

50) Most Frequent Value: (max and set)

You can find most frequent elements in a list with this short application:

lst = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]
print(max(set(lst), key = lst.count))

51) Advanced Python function parameters: (Lambda, Comprehension, Conditionals)

Python is a power house with endless capabilities and twists. Here is more one-liner approach for you.

Instead of this:

result = 0
for i in range(10):
    if i % 2 == 0:
        result += i

You can do this:

sum(i for i in range(10) if i % 2 == 0)

52) Creating Copies: (list copy method & dict copy method)

Next trio is for copying operations. Copying can be tedious. It can cause conflicts or confusion. It’s also extremely useful and something we do day in day out. Nevertheless it can be important to know some of the intricacies. Let’s start simply with the copy method:

lst1 = ["yellow", "gray", "brown"]
lst2 = lst1.copy()

dict1 = {'Fruit': 'Melon', 'Dessert': "Ice cream"};
dict2 = dict1.copy()

53) Creating Copies: (Slicing)

You can also use slicing to create copies. You may wonder why do I even have to slice it while I can just assign the whole variable. This would create identical objects in the memory which will create problems such as changing one object can change the other one etc.

Identical objects are checked by (is – is not) operators.

Thankfully Python slice notions are super cool:

lst1 = ["yellow", "gray", "brown"]
lst2 = lst1[:]

Please note that immutable objects such as string and tuples don’t have copy methods since they will always refer to the same memory ID as long as 2 strings or 2 tuples have the same exact values.

However, copy methods create a copy by reference which means copy points to the original.

If you’d like to create a completely different copy by creating new values in the memory this can be achieved by the next trick: deepcopy

54) Copy Library: (Deepcopy)

We have seen ways to create shallow copies now let’s see a way to create a deep copy:

import copy

lst1 = ["yellow", "gray", "brown"]
lst2 = copy.deepcopy(lst1)

55) Swap Values: (One-Liner)

Python has the most straightforward approach to swapping values out there.

a,b = b,a

56) Encoding: (utf-8)

29- encoding=’utf8′

Sometimes after opening a text file in Python you’ll get an error like: 

UnicodeDecodeError: ‘charmap’ codec can’t decode

That’s because decoding of the data defaults to system defaults and it can fail if you don’t specify the code when reading the file; just add the correct codec with encoding argument (usually utf8):

open(filename, encoding=’utf8′)

57) Ascii Conversions: (ord)

Ascii is a primitive (today) encoding standard that was dominantly popular through 60s 70s and 80s.

Before Ascii there was 6 bit encoding systems which is 2^6 (64 characters) and Ascii came as an expansion revision with 7 bit code enabling mapping of 2^7 (128 characters). It was always 1byte which is 8bit but the values from 128 to 256 weren’t defined initially.

Today, Ascii usually means 8bit which equals 2^8 (256) characters mapped. 8 bit also equals 1 byte and Ascii is a 1 byte or single byte encoding system.

So, after the background story here is what ord will do. 

  • ord function will tell the integer value (0 to 256) of a character

58) Ascii Conversions: (chr)

Today, UTF-8 became the global standard encoding for data traveling on the internet. That stands for 8-bit Unicode Transformation Format.

  • chr function will tell the character of an integer value (0 to 256) based on Ascii mapping.

59) Identity Operators: (is & not is)

is – is not are identity operators and they will tell if objects are exactly the same object or not.

print(a is b)
print(a is c)
print(a is not b)

60) with open as: (work on open file)

You can use with open as to work on files in a more practical way. (This eliminates the need to open and close files in multiple steps).

Code would go something like:

with open('research.csv') as f:
    data = csv.reader(f)
    for i in data:

61) Bin for bits: (And a little bit of computer history)

So how did it all start? From one-upping the oil candle technology to the age of Netflix, Tinder, Instagram, face recognition, self-driving vehicles, going to Moon, going to Mars, global computer programming literacy movement, decentralized AI, autonomous drones… And even maybe soon Singularity!

As you are reading these letters they are literally traveling as ones and zeros possibly all the way accross Atlantic Ocean via fiber-optic cables to your home. Next 3 tips are for people who might be interested in bytes and bits which is a system representing these ones and zeros. 

This might sound trivial but it’s really not that trivial even for high level programmers or any human in that sense. This is where it all started as far as computers go. I think as a coder everyone should at least take a couple of minutes to understand “bits” just as much as it makes sense for a carpenter to understand what a tree is or something like that.

Also, if you watched imitation games, an incredible true story about Alan Turing the man who founded the first modern computer (Turing Machine – 1936) which was followed by first digital computers such as ABC computer (without CPU hence not programmable) and ENIAC computer (considered to be the first functional digital computer) in late 30s and 40s. These all had a common feature: vacuum tubes. These are like light bulbs which go on and off, on representing 1 and off representing 0. Add enough of these values together and you have digital data. Hurray!

Also ComputerHope has a really awesome article about Computer Development History that’s worth reading.

So, if that story doesn’t impress you I don’t know what will but one bit represents 1 value of 2 possibilities, 0 or 1. This whole idea literally is the foundation of all computation and electronics we have and use today.

1 byte on the other hand represents 8 bits which equals 2^8 = 256 possibilities.

Python function bin will tell you the bit equivalent of an integer (or amount of possibilities):


62) Bit Length: (How many bits do you need?)

Note that integer 4 actually represents 5 values including 0 hence 3 bits are needed.

100 –> 4
101 –> 5



63) to_bytes: (Numbers to Bytes)

Finally, to_bytes method of integers will show the byte representation of an integer in hexadecimal base.

Hexadecimal base represents 16 values or 4 bits hence 2 hexadecimal values equal 1 byte or 8 bits. Hex is used in computer science since it much more convenient than 10 base numbers system when dealing with bits. 1byte can be represented in 2 hexadecimal values. Also conveniently, each memory address is 4bits which equals 1 nibble.

1 nibble = 1 hex = 4 bits = 2^4 values

1 byte = 2 nibbles = 8 bits = 2^8 values

b=a.to_bytes(2, byteorder="big")

d=c.to_bytes(2, byteorder="big")

x00 means Null in hexadecimal base. Showing unused bytes. Remember we chose 2 bytes, 1 would be enough.

0-9 are used for values 0 to 9 and
a-f are used for values 10 to 15
making 16 values total.

That’s why 15 shows as x00\x0f (0000_1111) –> 0 for 0 and f for 15
200 shows as x00\xc8 (1010_1000) –> c is 11 and 8 is 8

Only second bytes are used (which is 2 nibbles which are 4 bits each)
Byteorder signifies byte representation in descending or ascending order respectively “big” or “little”

64) Vim: (coolest code editor)

Do you wanna feel like the hacker in Swordfish? Regardless of your answer VIM is addictively cool and useful. It lets you code Python from Command Prompt and will work even when there is no system installed in a highly restricted computer.

VIM is super fast, crash-free and powerful. But there is more than that, VIM is also highly customizable with many extension and plugin opportunities.

You can see all the tips regarding installation and usage of Vim in this Vim Tutorial we prepared to get you started. It’s open-source and free (or rather charityware).

To Start Running VIM:

  • Just type vim from a command prompt such as Anaconda Prompt.
  • If you see a new window filename at the top and “–INSERT–” at the bottom bar, you’ve successfully launched VIM.
  • Now, VIM has 2 main modes: Editor and Command mode.
    • Editor Mode: You can switch to editor mode by pressing “i
    • Command Mode: You can switch to command mode by pressing “Esc
  • While in Editor Mode you can type your code or anything
  • To save and/or quit you need to switch to command mode and type appropriate commands. Commands are written starting with colon “:
    • Here are some examples:
      • :q >>> Quits without saving
      • :w >>> Saves without quiting
      • :qw >>> Saves and quits

Note: Please note that you should install Vim as an Administrator otherwise Command Prompt will fail to recognize Vim. Vim installer options exist for most OS out there such as MacOS, Linux, Ubuntu, Windows 64Bit or 32 Bit.

65) Random Numbers: (import random)

Python’s default random library can be very handy when you need to create random numbers.

randint for an integer between lower and upper limits:

import random

a=random.randint(33, 333)

randrange(start, stop, steps), will also give a value in the range but you can also specify a step.

import random

a=random.randrange(0, 50, 8)

random() will return a float value between 0 and 1. This can also be used as a random percentage.

You can explore other methods of the random library by using dir(random) and help(random)

import random


66) Opening a Web Page: (webbrowser library)

Here is an easy recipe to open web pages from within your Python terminal or code.

import webbrowser


67) Deque: (Sequences with double ends)

A deque or (Double ended queue) is a two ended Python object with which you can carry out certain operations from both ends.

It can be used when a collection is needed to be operated at both ends and can provide efficiency and simplicity over traditional data structures such as lists.

It also belongs to the standard collections library in Python.

Let’s check out some of the basic operations of deque:

import collections
a = collections.deque()


a.extend([200, 300, 400])
a.extendleft([3, 2, 1])



deque([4, 100])
deque([1, 2, 3, 4, 100, 200, 300, 400])
deque([2, 3, 4, 100, 200, 300])
deque([100, 200, 300, 2, 3, 4])
deque([200, 300, 2, 3, 4, 100])

68: Greatest common divisor: (math library)

Python’s standard math library has great methods that make almost any basic math calculation a breeze. Here is .gcd() method showing the greatest common divisor:

import math


69) Play Audio: (os library)

Python’s native os library is also capable of playing audio files. If you have a default player like VLC it will automatically play the audio in that program.

This could easily be used to create scripts like a super cool personal alarm, sedentary warning, reminder, motivation programs etc.

import os

70) Jupyter Notebook (Shortcuts & Line Magic)

Jupyter Notebook can be fantastic for learning, teaching and experimenting. Here are some ways to make it even more fantastic: shortcuts.

Only the most common shortcuts are shared here.

Command Mode
Enter enter edit mode
Shift Enter run section, skip to next section
Ctrl Enter run section
↑ , ↓ or k , j selects cell above or below
a , b inserts cell above or below
x , c , v cut , copy , paste cell
Shift v paste cell above
z undo last cell deletion
dd delete selected cell
Shift m merge cell below
Ctrl s saves
Edit Mode
Tab code completion or indent
Shift Tab tooltip
Ctrl ] indent
Ctrl [ deindent
Ctrl a selects all
Ctrl z undo
Ctrl Shift z redo
Jupyter Notebook Magic
%matplotlib inline allows graphic output within notebook
%%timeit Tab to measure the performance of processes (explained in #78 also)
%cls clears the screen
%cd to change the directory
%paste pastes from the clipboard
%source displays the source code of an object

You can really step up your Jupyter game by taking a quick look at these shortcuts!

Advanced Level

Here are more Python tips about relatively more complex Python concepts.

71) Annotated Assignment Statement: (:)

This might not seem as impressive as some other tricks but it’s a new syntax that was introduced to Python in recent years and just good to be aware of.

Annotated assignments allow the coder to leave type hints in the code. These don’t have any enforcing power at least not yet. It’s still nice to be able to imply some type hints and definitely offers more options than only being able to comment regarding expected types of variables.

Check out some of these examples:

day: str = 'Saturday'

lst: list = [1,2,3]

The slightly less cool and older implementation would be like this:

day= 'Saturday' #str

lst= [1,2,3] # list

You can read Python Official Documentation about Annotated Assignments here.

72) Yield Statement: ()

You can think of yield statement in the same category as the return statement. The difference is, while return statement returns a value and the function ends, yield statement can return a sequence of values, it sort of yields, hence the name.

If you’re interested in algorithms, here is a nice demonstration of Bubble Sort Algorithm Visualization where you can see how yield is needed and used.

Also, here are a couple of examples with yield statement:

def f1(a):
    yield a
    yield a**2
    yield a**3
print (f1(5))

for i in f1(5):
    print (i)    
<generator object f1 at 0x00000275EF339AC8>
def f2(b):
    for j in range(b):
        yield j

for i in f2(5):

73) News brought to you by: (Python Newspaper)

Another fabulous Python library newspaper3k gives a whole another meaning to newspaper access.

Sleek businessperson reading business newspaper

You can install newspaper3k via pip from your Anaconda Command Prompt. If you need more instructions you can check out this article regarding how to install packages using pip with Anaconda.

pip install newspaper

After installing newspaper3k you can start using it. Here are some examples:

import newspaper

paper ='')

for article in paper.articles:

Code above will list all the articles found in the entire newspaper.

Check out the code below to see all the other attributes you can conveniently extract from a single article or a whole newspaper.

Information is power, when managed well it can offer great contributions to specific tasks, projects and objectives.


from newspaper import Article

url = ''
article = Article(url)


You can see the Github repository of this cool Python library here: Newspaper 3k Github

74) Geopy: (Work on Open File)

Geopy is another great library that can be used for geocoding services. Converting open addresses to longitude and latitude values or converting coordinates to addresses is called geocoding. It’s a common application with almost any location related service such as media sharing, social network, navigation, transportation, streaming, gaming, websites, communication, identification, security etc.

Here are some simple examples to demonstrate what you can quickly do with geopy library using the address of New York rooftop bar 230 Fifth.

Please note that you might need to change the user_agent to avoid application errors. One common error related to user_agent is InsufficientPrivilege Error.

from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="HiApp")
location = geolocator.geocode(" 230 Fifth Ave, New York")

230, Fifth Avenue, Sheridan Meadows, Amherst Town, Erie County, New York, 14221, United States of America
print((location.latitude, location.longitude))

(42.983481438214326, -78.70683044449504)

{'place_id': 259174015, 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0.', 'osm_type': 'way', 'osm_id': 12316939, 'boundingbox': 
['42.983431438214', '42.983531438214', '-78.706880444495', '-78.706780444495'], 
'lat': '42.983481438214326', 'lon': '-78.70683044449504', 'display_name': '230, 
Fifth Avenue, Sheridan Meadows, Amherst Town, Erie County, New York, 14221, 
United States of America', 'class': 'place', 'type': 'house', 'importance': 0.511}

Open Street Map’s Nominatim is a very convenient geocoding service but you should check their official documentation for any serious use case.

Some other similar web services are Geonames, Yandex Map API, Bing Map API, Google Maps API V3 and Yahoo BOSS Finder. They all offer different usage benefits.

Big Apple and Lake States Satellite View at Night

75) sh: (Shell scripts and bash commands)

sh is a subprocess wrapper that can be used to dynamically map system functions to Python. It facilitates writing shell scripts with bash features.

Unfortunately latest version of sh only works for linux and Mac. If you’re using Windows you’ll need to install an old version that can be found here.

Let’s check out some examples of what can be done with sh:

import sh

Here are some other ideas:

import sh

sh.echo('Hello World')

76) Decorators: (Augmenting functions without modifications)

Decorators are another elegant representative of Python’s expressive and minimalistic syntax.

By using decorators you can change a function’s behavior or outcome without actually modifying it.

In other words decorators decorate functions to make them fancier in some way.

A decorator starts with @ sign in Python syntax and is placed just before the function.

Here are some simple examples:

Let’s say we have a simple function that adds 2 numbers.

def adder(a, b): 
    return a+b
print(adder(2, 3))

Now, without touching the original function, let’s decorate it so that it multiplies the result by 100.

def decoten(func): 
    def times10(x, y): 
        return func(x*10, y*10) 
    return times10

def adder(a, b): 
    return a+b 


77: Memory Optimization: (__slots__)

At the advanced level Python can have

When you start editing default Python implementations for speed and efficiency reasons you know you’re starting to get into the expert territory.

Python classes utilize dictionaries for instant attributes by default which can take quite a space even when you’re constructing a class object.

When this is the case you can use __slots__ magic to force Python not to have a big chunks default instance attribute dictionary and instead have a small custom list. This can save lots of memory in suitable applications.

On top of that, another benefit of __slots__ is faster access to class attributes.

class Team:
    __slots__ = ["name", "score"]
    def __init__(self, name, score): = name
        self.score = score

a=Team("Real Madrid", 5)
print(, a.score, sep=" : ")
Real Madrid : 5

78) Time it: (Time Processes)

timeit library is great for timing Python execution times. Just pass a function in string format to timeit.timeit() method and it will carry out 1 million executions to report the minimum time the code takes.

Its very useful to compare small code pieces and different functions but can be sluggish with big code.

Check out the example below demonstrating the execution time difference between 2 very similar list comprehension methods in Python:

import timeit

lst2='''[i for i in range(1000)]'''


print(x, y, sep="------")
11.646945999999843 ------- 27.643676500000083

timeit library is great for timing Python execution times. Just pass a function in string format to timeit.timeit() method and it will carry out 1 million executions to report the minimum time the code takes.

Its very useful to compare small code pieces and different functions but can be sluggish with big code.

Check out the example below demonstrating the execution time difference between 2 very similar list comprehension methods in Python:

79) Virtual env: (Managing Dependencies)

Virtual Environment lets programmer create a specific environment with different versions of libraries when needed.

When the developer needs only certain versions of modules and libraries because development requires it virtual environment can be a practical solution.

It’s also quite straightforward with Python.

Make sure virtualenv module is installed (Installed by default in Anaconda3)

pip install virtualenv

To create a virtual environment type virtualenv followed by an environment name you’d like:

virtualenv environment1

you can also activate and deactivate a virtual environment simply by typing:

activate environment1


You’ll need to activate your specific virtual environment before installing a specific module with a specific version. Once you are done working in that environment you can deactivate it and go back to base.

80) Groupby from itertools: (Grouping Python Data)

If you have iterables with elements belonging to different groups, you can use itertools’ groupby method to group them and process items in groups.

Here is an example:

from itertools import groupby

lst = [("car", "Ferrari"), ("car", "Renault"), ("country", "France"), ("country", "New Zealand"), ("fruit", "Kiwi")]

for i, group in groupby(lst, lambda x: x[0]):
    for j in group:
        print ("{} is a {}.".format(j[1], val))
Ferrari is a fruit.
Renault is a fruit.

France is a fruit.
New Zealand is a fruit.

Kiwi is a fruit.

81) Transposing Data: (zip method)

This trick is simple yet genius and can be very useful sometimes.

You can combine zip function and * unpacking notation for *args appropriate objects.

mat = [[1, 2, 3], [1000, 2000, 3000]]
[(1, 1000), (2, 2000), (3, 3000)]

82) Working with Zipped files: (ZipFile Library)

As you get more and more proficient with Python, you start experimenting more and more cases. One of these cases is encountering zip files whether it’s data science, game development, finance or scripting, zip files are a very common part of the digital world.

Let’s check out how zipfile library can be a super convenient and quick solution for zip related tasks.

First you can import zipfile as below:

from zipfile import ZipFile

There are many useful methods to be used with zipfile, here are some common ones:

  • Open: Opening with zipfile is more like creating a handle to work with. You can open a zip file in 2 ways: read; “r” and write; “w” depending on your use case.
from zipfile import ZipFile

f = ZipFile("", "r")
f = ZipFile("", "w")
  • Get file names: You can have a list of all the files’ names returned using namelist() method
from zipfile import ZipFile

f = ZipFile("", "r")
['app.html', 'credits.html', 'app.css', 'auth.css', 'bridge.css', 'history.css', 'd3dcompiler.dll']
  • Extract files:
from zipfile import ZipFile

f = ZipFile("", "r")
  • Read & Write:
from zipfile import ZipFile

f = ZipFile("", "r")"FF/app.html")
  • Please note that during the write operation zipfile is specifically opened with “w” parameter.
from zipfile import ZipFile

with ZipFile("", "w") as f:

83) Time library: (More Time Functions)

Time library provides lots of time related functions and methods and is good to know whether you’re developing a website or apps and games or working with data science or trading financial markets. Time is essential in most development pursuits and Python’s standard time library comes very handy for that.

Let’s check out a few simple examples:


import time


Cool tube clock showing current time

84) getsizeof: (Sys Library)

getsizeof() method from Python’s sys library will tell you the size of a Python object in the memory. Let’s see an example:

import sys

The result is in bytes.

Getsizeof() will give the size of any Python object whatsoever. Range object, byte object, reversed object, list object, dictionary object, list goes on.

Let’s create a huge list and see its size in bytes:

import sys

Wow, 9MB in memory. Talk about a big list!

85) Named Tuples: (From Collections Library)

Named Tuple is such a sophisticated data type and it lets you create exactly what the name says and more.

Namedtuple is a:

  • Light object
  • Readable
  • Allows creating attributes
  • Callable by names
  • Comes with object notation
from collections import namedtuple

flights = namedtuple("flight", "price, distance")
US = flights(2000,5000)
Iceland = flights(500,500)
France = flights(1000,1000)


86) Animated Charts: (Save as Gif or Mp4)

Visualization is big in Python. Matplotlib is a well-known library for charts but something super fancy and useful for visualization purposes that goes unnoticed is animated charts possibility in Matplotlib Animations.

Although the function itself, which is FuncAnimation module from matplotlib.animation library, is straightforward itself, there are some parameters that can get confusing such as figure itself, update function for animation, saving options such as codecs, fps settings, FFMpegWriter, PillowWriter, saving as gif, saving as mp4 or avi etc.

We have 2 great tutorials that you can check out explaining:

How to create a Matplotlib Animation

How to save a Matplotlib Animation

In short a matplotlib animation is created with 2 major pieces:

  • Figure –fig here: a figure window (can be initialized as plt.figure)
  • Animation function –animate here below: an animation function that continuously updates the figure

For a more detailed walkthrough please visit the individual Python animation tutorials mentioned above.

import random
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig = plt.figure(figsize=(15,15))

x,y = [], []
index= count()
def animate(i):

ani = FuncAnimation(fig, animate, interval=300)

87) All or any: (or & and Alternatives)

Any & all are similar to or & and.

  • Any returns True when at least 1 of the statements is True
  • All returns True when all statements are True

Here are some examples:

any([False, False, False])
all([False, True, True])
any([True, False, False])
any([False, False, True])
all([True, True, True])

88) Recursive Functions: (Functions calling themselves)

Recursion in programming is a very powerful algorithmic phenomenon that helps question to be solved by solving mini pieces of the problem and continuously feeding the answer or solution back to the problem.

Because of this nature, it goes hand in hand with concepts such as iteration (think for loop or while loop), yield statement (in Python), user-defined functions, algorithms.

Recursive programming is a broad subject and it can go well beyond these Python concepts but solving a problem within Python’s syntax and structure can also be infinitely interesting at the micro level.

Let’s look at a commonly known number sequence to demonstrate a simple recursion idea in Python:

Fibonacci number is calculated by adding 2 numbers preceding the current Fibonacci number. When it’s continuously done it gives Fibonacci Sequence:

Fib(n-2) + Fib(n-1) = Fib(n)

So it goes,

0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 ….

Let’s put it in code:

def fibo(x):
    if x <= 1:
        return x
        return fibo(x-1) + fibo(x-2)
for i in range(40):
    print(fibo(i), end=" || ")

This code will return 1 for fibo(1) and 0 for fibo(0). After that it starts an infinite recursion. fibo(2) is fibo(1)+fibo(0) and fibo(3) is fibo(2)+fibo(1).

0 || 1 || 1 || 2 || 3 || 5 || 8 || 13 || 21 || 34 || 55 || 89 || 144 || 233 || 377 || 610 || 
987 || 1597 || 2584 || 4181 || 6765 || 10946 || 17711 || 28657 || 46368 || 75025 || 121393 ||
196418 || 317811 || 514229 || 832040 || 1346269 || 2178309 || 3524578 || 5702887 || 9227465 ||
14930352 || 24157817 || 39088169 || 63245986 ||

89) Cache results with decorators: (Efficient Functions)

There is a great way to cache functions with decorators in Python. Caching will help save time and precious resources when there is an expensive function at hand.

Implementation is easy, just import lru_cache from functools library and decorate your function using @lru_cache.

Here is an example:

from functools import lru_cache

def fibo(x):
    if x <= 1:
        return x
        return fibo(x-1) + fibo(x-2)

for i in range(50):
    print(fibo(i), end="|")

print("\n\n", fibo.cache_info())

Furthermore, you can also ask for a cache status report using cache_info().

CacheInfo(hits=96, misses=50, maxsize=None, currsize=50)

Hits and misses show cache hits and cache misses that occurred during operation. 

Cache hit roughly denotes when a value is looked up in the cache and is found in the cache and cache miss is when a value is looked up but can’t be found in the cache.

Currsize signifies the current size of cache or in other words how many items have been cached, in this case 50, basically all of them, and maxsize is the maximum allowed items allowed to be cached, in this case None because we specified maxsize to be None in the beginning.

90) Textblob: (Sentiment Analysis)

Sentiment analysis is a term used to refer to the techniques that aims to extract sentiments, emotions or tone from a text. With the advancements in computation power and technology and accumulation of text (social media, online books, news, translation of ancient scripts etc.) Natural language processing (NLP) has become a very interesting and significant field in the last decade.

Textblob is a fantastic library that can be used for sentiment analysis and more. Sentiment can be used to tell the features of a text such as tone positivity, subjectivity, objectivity, hopefulness, kindness, explicit language, grammar analysis, translation,  spelling check, etc etc.

This method is currently being used by multiple hedge funds to analyze social media and online news to identify trading opportunities and analyze companies, markets, indexes, economies, stocks and commodities.

It can also be used to analyze political stability, global events, crisis management, books, articles, social media profiles and more.

Here is a simple demonstration from a random book:

from textblob import TextBlob

f = r"c://Users/USA/Desktop/asd.txt"
file = open(f, "r", encoding="utf8")
data= (

blob = TextBlob(data)

Spending time together is like playing in the anteroom of heaven.
  • First TextBlob module needs to be imported
  • Then a blob object needs to be created with the text being analyzed
  • And you can start sentiment analysis right away after that
  • There are already lots of convenient methods and attributes included such as:
    • .tags
    • .noun_phrases
    • .sentiment
    • .sentiment.polarity
    • .words
    • .sentences
    • .lemmatize (grouping similar words for analysis based on context)
    • .definition
    • .correct()
    • .spellcheck()
    • .words.count()
    • .ngrams()
Note: If you don’t have textblob library installed, you can refer to this installation tutorial.

.sentences returns a list of sentences from the text and here we’re printing only the 1st sentence (index 0). Here is what .tags will return:

[('Spending', 'NN'), ('time', 'NN'), ('together', 'RB'), ('is', 'VBZ'), ('like', 'IN')]
Sentiment(polarity=0.0059523809523809494, subjectivity=0.5603174603174603)

Polarity here refers to a sentiment range between -1 and +1, from most negative to the most positive. Subjectivity can take a value between 0 and +1, 1 being the most subjective text possible while 0 signifies maximum objectivity.

Let’s see the last 5 words this time:

['mountains', 'huge', 'become', 'now', 'love']

And definition of the last word:

['a land mass that projects well above its surroundings; higher than a hill', 
"(often followed by `of') a large number or amount or extent"]

You can also check out this sentiment analysis tutorial with textblob for more examples.

91) Kwargs: (Arguments for named sequences)

**kwargs and *args are function arguments that can be very useful.

They are quite underused and often under-understood as well. (Sorry couldn’t resist that)

Let’s try to explain what kwargs are and how to use them.

  • While *args are used to pass arguments at an unknown amount to functions, **kwargs are used to do the same but with named arguments.
  • So, if *args is a list being passed as an argument, you can think of **kwargs as a dictionary that’s being passed as an argument to a function.
  • You can use arguments as you wish as long as you follow the correct order which is: arg1, arg2, *args, **kwargs. It’s okay to use only one of those but you can’t mix the order, for instance, you can’t have: function(**kwargs, arg1), that’d be a major faux pas in Python.
  • Another example: You can do function(*args,**kwargs) since it follows the correct order.

Here is an example. Let’s say satelites are given with their names and weight in tons in dictionary format. Code prints their weight as kilograms along with their names.

def payloads(**kwargs):
    for key, value in kwargs.items():
        print( key+" |||", float(value)*1000)

payloads(NavSat1 = '2.8', BaysatG2 = '5')
NavSat1 ||| 2800.0
BaysatG2 ||| 5000.0

Since the function above would work for any number of dictionary keys, **kwargs makes perfect sense rather than passing arguments with a fixed amount.

Also ** syntax can be used to unpack while calling a function. Check out this example:

def payloads(**kwargs):
    for key, value in kwargs.items():
        print( key+" |||", float(value)*1000)

sats={"Tx211":"2", "V1":"0.65"}
Tx211 ||| 2000.0
V1 ||| 650.0

92) Compile a regex formula: (Advanced Regex)

You can also compile regular expressions in Python.

Regex has a massive place in working with all kinds of text, database queries, strings, search engine queries, tables, web data etc.

Python comes with a standard regular expression library called re. If you’re new to regex and would like to learn more you can check out this extensive:

Python Regular Expression Tutorial


Python Regular Expression Exercises (Online & Interactive)

So in this tip we will check out how regex can be compiled and the benefits of doing so.

Normally, when you use a regex expression Python will compile it during the execution of your program and it won’t really make a difference if regex is compiled before hand or not. Especially since Python also caches regular expressions the performance benefits of separately compiling regex is not expected to be significant.

However, some main benefits of compiling regex are reusability and readability.

On top of that it can make sense to compile some regex expressions ahead of execution so that compilation is not done at a random or even worse critical moment when running the program.

Check out this simple example to understand how regex can be compiled in Python:

Regular Expression without compiling:

import re

str='''Chuck Norris can divide by zero.
When Chuck Norris falls in water, Chuck Norris doesn't get wet. Water gets Chuck Norris.
Chuck Norris once visited the Virgin Islands. They are now The Islands.'''

result2 = (re.match('[A-Z][a-z]*\s\S*', str))

Regular Expression Compiled Example:

import re

str='''Chuck Norris can divide by zero.
When Chuck Norris falls in water, Chuck Norris doesn't get wet. Water gets Chuck Norris.
Chuck Norris once visited the Virgin Islands. They are now The Islands.'''

query = re.compile('[A-Z][a-z]*\s\S*')
result1 = (query.match(str))


93) Create a File Server: (A Surprising One Liner)

This one is kind of well-known. Still very impressive nevertheless.

At the comfort of your command prompt (we recommend Anaconda Prompt), you can create an HTTP server with a tiny one line Python command like below:

python -m http.server 8000

Number in the end here is the Port Number.

python https server

Server will start immediately. If you’d like to kill the server just pres Ctrl+C and server will be interrupted as above or you can just close the Prompt Window.

If you’d like to make sure you can type ps from the Command Prompt to see all the processes. Scroll up to and you will see a Python process when the server is running which will be shut down after you stop the server.

Please note that if you have other instances of Python running such as Spyder or any Python IDE or Python itself, these processes will also appear under Python in the list.

python https server process list
  • You can access you Python file server by navigating to localhost:8000 (Or whatever port you chose) from your browser’s address bar.
  • It’d be wise to open the server on a dedicated not-so-important folder somewhere in your computer. i.e.: You can create a new folder on your desktop, navigate to that directory using cd command and start the server within there.
Python file server directory

You can get Spyder inside Anaconda Individual Package for free here.

Or if you wish you can also get Spyder IDE individually from this link.

94) Enum Class: (Members with unique ID values)

Here is another classy approach from Python, no pun intended. Python’s enum class will let you create enum object members with constant and unique values which then can be listed, compared or used for identification. 

Enum classes are also iterable so they can be iterated as well:

Here is a simple example: 

from enum import Enum

class sports(Enum):
    skiing = 0
    soccer = 1
    running = 2
    football = 3
    golf = 4
    swimming = 5
< 4>

Python enum class iteration example:

for i in sports():
<sports.skiing: 0>
< 1>
<sports.running: 2>
< 3>
< 4>
<sports.swimming: 5>

95) Connect to Database: (SQLite)

Database is such a powerful concept to store data. Apps use it, software uses it, websites use it. It’s not that hard and you can also use it.

But then when you combine Database programming with Python, that’s real power.

SQlite is a nice open-source application that works well with Python.

All you need to do is type a few Python codes and implement your SQL code inside. It will be something like this:

import sqlite3

q = sqlite3.connect('Mydatabase.db')
cursor = q.cursor()

cursor.execute('SELECT id, name FROM Prices')
data = cursor.fetchall()
for i in data:


  1. First connect to database via sqlite3 (sqlite3.connect(‘Mydatabase.db’))
  2. Create a cursor (q.cursor())
  3. Then, cursor.execute for executing Database Commands.
  4. .fetchall() to get data from the Database Rows 
  5. Finally close the cursor and terminate the connection (cursor.close() and q.close())

96) StringIO, cStringIO and BytesIO: (Python Streams)

These very potent, practical but unused methods can mean the difference between hardcore performance and inefficient operations.

Generally Python stream is a file-like object that exists in the Ram of the computer instead of the Disk IO. Ram is much faster than Disk and can be perfect for parts of the program that’s running.

That’s why lots of software has some kind of Ram usage and you can implement it too.

  • StringIO is used with unicode objects (like strings) and it will accept any string with Unicode encoding
  • BytesIO is used with byte data (binary input)
  • cStringIO is like StringIO since it’s a C implementation but there is a catch, cString won’t accept any string that can not be encoded as plain Ascii, which can be limiting depending on the situation.
All of these methods will provide a file like object to write data.
import StringIO

str = "Hello World"
file = StringIO.StringIO(str)

print (
Hello World

97) Work with gzip files in Python: (gzip library)

Gzip or gnu is a compression algorithm that can provide lots of compression benefits with large files. You might have seen it before as a file which uses .gz extension. Since gzip only works for a single file you might also have seen the tar archive solution which combines multiple files before creating gzip compression resulting in a tar.gz (or tgz) file.

Python has a great gzip library that makes working with gzip files a breeze.

Here is a super simple demonstration of compressing a Python list: 

import gzip

str = b"Hello World"
c_str = gzip.compress(str)

That was too easy because our string was in byte format already b””.

Because compress() method takes byte data only. So, sometimes you might need to make that conversion but it’s not that complicated once you know it.

Here is another example where a regular string is “prepared” for compression:

  1. First, string is going to be converted to bytes using bytes() function 
  2. And second, “utf8” is passed as encoding parameter in the bytes function.
import gzip
str = "Hello World"
str = bytes(str, "utf8")
c = gzip.compress(str)

So, what if you want to compress Python objects such as lists, dictionaries, tuples or files and images. In each case you will need to do appropriate conversions so that data is ready for compression. Here is an idea to compress a list: First it’s converted to string and then compressed. Similar methods can be used with JSON method.

import gzip

lst = ["kiwi","apple","banana"]
lst = str(lst)
lst = bytes(lst, "utf8")

Decompression part is the reverse of a compression process and somewhat more straightforward:

import gzip
dec_lst = gzip.decompress(c_lst)

Finally, you can also use open() method to open gzip files and work with them.

open with structure can also be useful in this case:

with"textfile.txt.gz", "rb") as file:
	data =

98) Memory Management: (getrefcount method)

getrefcount will show how many times an object is used in the memory. It’s a fantastic tool that can be used for memory management in any program and it’s very convenient too. 

Getrefcount will calculate the object usage at a low level ByteCode so it can tend to be higher than expected. For instance when you print a value that value is actually processed multiple times in the background inside the print function itself and getrefcount also counts the instance when the value is called with getrefcount method itself. So, it’s safe to say that the count will actually always be at least 1 time higher than expected.

Here is a code to show how many times alphanumeric characters are referenced in a random code:

It makes sense to see that x, i and y are so frequently utilized.

import sys
import matplotlib.pyplot as plt
#string with all character letters
str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
x_ax = [sys.getrefcount(i) for i in str]
y_ax = range(len(str))
Graph = plt.figure(figsize=(250,150)), x_ax, align='center', color="orange")
plt.xticks(y_ax, str)


This code will show reference counts for 2 random variables: First an integer that gets increased by 1, second, a random word that’s not likely to be used anywhere else in the backend of the functions (Heritage).

Interestingly first variable (integer 10) is referenced 309 (minus one) times in the kitchen of this little program. Second variable is never used except our assignment and reference count attempt which adds up to 3 times. Cool trick?

a_val = 10
a_val += 1

b_val = "Heritage"

a = sys.getrefcount(a_val)
b = sys.getrefcount(b_val)

print(a, b, sep="\n")

99) os.environ: (environment variables)

environ is a very cool module from Python’s default os library.

You can access all environment variables in your operating system using os.environ.

It works in a dictionary format and lists all the variables. Let’s see:

import os

Above code will give you a raw and messy output to the human eye. But, you can specify which data you’d like to extract with os.environ as well.

Since it’s in dictionary we can tweak the code a little bit to make everything more readable, also it’s an opportunity to use the pprint library:

{‘ALLUSERSPROFILE’: ‘C:\\ProgramData’,
‘APPDATA’: ‘C:\\Users\\ABC\\AppData\\Roaming’,
‘CLICOLOR’: ‘1’,
‘COMMONPROGRAMFILES’: ‘C:\\Program Files\\Common Files’,
‘COMMONPROGRAMFILES(X86)’: ‘C:\\Program Files (x86)\\Common Files’,
‘COMMONPROGRAMW6432’: ‘C:\\Program Files\\Common Files’,
‘CONDA_PREFIX’: ‘C:\\Anaconda3’,
‘DRIVERDATA’: ‘C:\\Windows\\System32\\Drivers\\DriverData’,
‘GIT_PAGER’: ‘cat’,
‘HOMEPATH’: ‘\\Users\\ABC’,

‘PROCESSOR_IDENTIFIER’: ‘Intel64 Family 6 Model 158 Stepping 10, GenuineIntel’,
‘PROGRAMDATA’: ‘C:\\ProgramData’,
‘PROGRAMFILES’: ‘C:\\Program Files’,
‘PROGRAMFILES(X86)’: ‘C:\\Program Files (x86)’,

‘TMP’: ‘C:\\Users\\ABC\\AppData\\Local\\Temp’,
‘USERPROFILE’: ‘C:\\Users\\ABC’,

import os
import pprint

100) Serialization: (pickle & Json)

Sometimes you may need to save your Python object locally for later use or Network transfers. Python has fantastic libraries for serialization such as Json and Pickle.

Serialization is storing data structures in the program so they don’t just disappear after the program is terminated.

There is also marshal library but it’s more primitive and can’t handle certain techniques such as class instances and recursion. Marshal is closer to json in its scope of serialization.

So, when would you use pickle, cpickle, json or ujson?

cpickle and ujson are faster versions of respective libraries that take advantage of C implementations in Python. So they’d always be favorable for speed reasons.

Apart from that, json is a more secure and readable version of serialization than pickle which comes at a cost of speed.

While you can take care of almost any data structure in Python with Json it gets inefficient with large files or uncommon objects. Pickle on the other hand operates in a sweet spot where you’d like to work with large files (multiple GBs) and still don’t want to be bothered with database solutions.

The thing is depending on your application, you may have to watch out for security vulnerabilities pickle introduces to the system so it’s usually wise to seek out json or database solutions before resorting to pickle when possible.

You can check out our JSON Tutorial explaining JSON solutions in Python.

Here is a quick pickle serialization and deserialization:

import pickle

lst = ["LAX", "LGA", "DEN", "SFO", "JFK", "MIA"]
a = pickle.dumps(lst)

['LAX', 'LGA', 'DEN', 'SFO', 'JFK', 'MIA']

Bonus) Abstract Base Classes: (ABC)

Abstract Classes are nice alternatives to concrete classes since they conveniently allow multiple inheritence.

They work well with unfinished, concept-like classes hence the name abstract. Abstract classes become functional with methods written in subclasses. When a developer is working with subclasses of an abstract class they know that the class is either incomplete or empty so this gives an opportunity to work with incomplete classes in a structured way. @abstractmethod is a useful decorator for abstract base classes in Python.

Here is an example with an @abstractmethod :

from abc import ABC, abstractmethod
class ClassAbstract(ABC):
    def __init__(self, val1):
        self.value1 = val1
    def under_construction(self):

class DDD(ClassAbstract):

    def under_construction(self):
        return self.value1
data1 = DDD(10)


While the example demonstrates abstract classes perfectly here are 2 “bad” examples to further elaborate abstract classes:

from abc import ABC, abstractmethod
class ClassAbstract(ABC):
    def __init__(self, val1):
        self.value1 = val1
    def under_construction(self):

class DDD(ClassAbstract):

    def multiplier(self):
        return self.value1*10
data1 = DDD(10)

TypeError: Can't instantiate abstract class DDD with abstract methods under_construction

You get the above error because you didn’t modify and complete the incomplete abstractmethod inherited from the abstractclass.

Let’s look at another troubled example:

In this example, abstractmethod is not enforced. This is only good old inheritence and not an abstractclass. It still works even though under_construction method is left untouched.

from abc import ABC, abstractmethod
class ClassAbstract:
    def __init__(self, val1):
        self.value1 = val1
    def under_construction(self):

class DDD(ClassAbstract):

    def multiplier(self):
        return self.value1*10
data1 = DDD(10)


Bonus) c classes: (cPickle, uJson and others)

If you are serious about execution speed then you should definitely consider mingling with C and C++ in relation with Python.

With the help of C extensions some Python operations can be sped up to 100x, 500x or 1000x.

The details of these concepts is beyond the scope of this Python tutorial but if you’re interested you should definitely check out Cython, distutils and setuptools.

Distutils and setuptools make it possible to write extension modules for Python written in either C or Python or even a mix code.

Cython is a Python-like languages that compiles like C catching up with C speeds in many cases.

CPython, often confused with Cython is a Python implementation in C and it requires writing C code for the most part but both will allow you to write libraries in C that can be implemented in Python such as Python’s standard library numpy.

You can also check out alternative libraries that are already written in C by the community. One example to that is uJSON, an ultra-fast alternative to Python’s standard JSON library, or cPickle as an alternative to Pickle.

Thank you for reading!

Please give a shoutout in social media or share if you find this page useful.

Recommended Posts