IHub Python BootCamp
IHub Python BootCamp
Python3 For
Beginners.
Subi Subi
Subi Subi
What is Python?
Subi Subi
Subi Subi
A High-Level Language
Python falls under the category of high-level, interpreted languages. A
high-level language is one which cannot be understood directly by our
machine. There is a certain degree of abstraction in its syntax. Machines are
generally designed to read machine code, but high-level syntax cannot be
directly converted to machine code.
Subi Subi
Subi Subi
Readability
One of the biggest reasons for Python’s rapid growth is
the simplicity of its syntax. The language reads almost
like plain English, making it easy to write complex
programs.
Subi Subi
Subi Subi
Applications
Subi Subi
Subi Subi
Subi Subi
Subi Subi
Table of Contents
● Data types & Variables
○ Intro
○ Numbers
○ Bools
○ Strings
○ “None”
○ String Slicing & Formatting
○ Grouping Values
○ Operators
■ Arithmetic
■ Comparison
■ Assignment
■ LoiHubal
■ Bitwise
○ String Operations
○ Grouping Values
Subi Subi
Subi Subi
Table of Contents
● Conditional Statements
○ Intro
○ The If statement
○ If-Else
○ If Elif Else
● Functions
○ Intro
○ Creating Functions
○ Function Scope
○ Built-In Str Function
○ Type Conversions
○ Taking User Inputs
○ Lambdas
○ Function As Arguments
○ Recursion
Subi Subi
Subi Subi
Table of Contents
● Loops
○ Intro
○ For… loop
○ Nested For… loop
○ Break , Continue Keywords
○ While… loop
○ Try… Except (Error Handling)
● Data Structures
○ Intro
○ Lists
○ Lists Operations
○ Tuples
○ Dicts
○ Dicts Operations
Subi Subi
Subi Subi
Table of Contents
● Data Structures
○ Sets
○ Set Theory Operations
○ Data Structure Conversions
● Libraries
○ Intro To Python Standard Library
○ Popular Modules
○ PyPi
● POOP (Iff Time Permits)
Subi Subi
Subi Subi
Subi Subi
Subi Subi
Subi Subi
Subi Subi
Every language has a different syntax for displaying or printing something on the
screen.
Since Python is one of the most readable languages out there, we can print data
on the terminal by simply using the print statement.
print (data)
print("Hello World")
By default, each print statement prints text in a new line. If we want multiple print
statements to print in the same line, we can use the following code:
Subi Subi
Subi Subi
Comments
Comments are pieces of text used to describe what is happening in the code. They
have no effect on the code whatsoever.
# each time
Subi Subi
Subi Subi
Subi Subi
Subi Subi
Python’s Data Types
The data type of an item defines the type and range of values that item can
have.
The concept of data types can be found in the real world. There are numbers,
alphabets, characters, etc., that all have unique properties due to their
classification.
Unlike many other languages, Python does not place a strong emphasis on
defining the data type of an object, which makes coding much simpler. The
language provides three main data types:
● Numbers
● Strings
● Booleans
Subi Subi
Subi Subi
Variables
Subi Subi
Subi Subi
Naming Convention
There are certain rules we have to follow when picking the name for a variable:
Subi Subi
Subi Subi
Naming Convention
● The _ character can appear anywhere in the name.
For example, _income or income_ are valid names.
For example, inc or even income would not give any useful information
but names like weekly_income, monthly_income, or annual_income
explain the purpose of our defined variable
Subi Subi
Subi Subi
Numbers
Subi Subi
Subi Subi
Integers
The integer data type is comprised of all the positive and
negative whole numbers.
In Python, 5 is considered to be an
flt_pt = 1.23456789
integer while 5.0 is a float.
print(flt_pt)
Subi Subi
Subi Subi
Complex Numbers
Python also supports complex numbers, or numbers made up print(complex(10, 20)) #
of a real and an imaginary part. Represents the complex
Just like the print() statement is used to print values, complex() number (10 + 20j)
is used to create complex numbers. print(complex(2.5, -18.2)) #
Represents the complex
It requires two values. The first one will be the real part of the
number (2.5 - 18.2j)
complex number, while the second value will be the imaginary
part.Here’s the template for making a complex number:
complex_1 = complex(0, 2)
complex(real, imaginary)
complex_2 = complex(2, 0)
Let’s see a few examples: print(complex_1)
print(complex_2)
Note: In normal mathematics, the imaginary part of a complex
number is denoted by i. However, in the code above, it is
denoted by j. This is because Python follows the electrical A complex number
engineering convention which uses j instead of i. Don’t let that usually takes up 32
confuse you. bytes of memory.
Subi Subi
Subi Subi
Booleans
The Boolean (also known as bool) data type allows us to choose between two
values: true and false.
print(True)
Note: The first letter
of a bool needs to
f_bool = False be capitalized in
print(f_bool) Python.
Subi Subi
Subi Subi
Strings print("Harry Potter!") # Double
A group of characters such as this is an example of
the string data type. quotation marks
Subi Subi
Subi Subi
The Length of a String
The length of a string can be found using the len() built-in function. This length
indicates the number of characters in the string:
Indexing
A string in Python is indexed from 0 to n-1 where n is its length. This means
that the index of the first character in a string is 0.
Subi Subi
Subi Subi
Accessing Characters
Each character in a string can be accessed using its index. The
index must be closed within square brackets, [], and appended
to the string. If we try to execute
print(last) len(batman) is
Subi Subi
Subi Subi
String Immutability
Once we assign a value to a string, we can’t update it later. How about verifying
it with an executable below?
string = "Immutability"
string[0] = 'O' # Will give error
The above code gives TypeError because Python doesn’t support item
assignment in case of strings.
str1 = "hello"
print(id(str1)) Notice, when we assign a new
str1 = "bye" value to str1 (at line 4) its identity
changes not the value.
print(id(str1))
Subi Subi
Subi Subi
ASCII Versus Unicode
Subi Subi
Subi Subi
Python offers another data type called NoneType. It only has a single value,
None. We can assign None to any variable, but we can not create other
NoneType variables.
Subi Subi
Subi Subi
String Slicing
Slicing is the process of obtaining
a portion (substring) of a string by
using its indices.
string[start:end]
string[start:end:step]
Subi Subi
Subi Subi
Reverse Slicing
Strings can also be sliced to return a reversed substring. In this
case, we would need to switch the order of the start and end
indices.
Subi Subi
Subi Subi
Partial Slicing
One thing to note is that specifying the start and end indices is optional.
If start is not provided, the substring will have all the characters until the end
index.
If end is not provided, the substring will begin from the start index and go all
the way to the end.
That’s pretty much all we need to know about string slicing. Play around with
the strings above to get a better understanding of how slicing works.
Subi Subi
Subi Subi
String Formatting
Subi Subi
Subi Subi
Inserting Strings Within a String
Subi Subi
Subi Subi
Inserting Integers Within a String
Subi Subi
Subi Subi
Inserting Floats Within a String
Subi Subi
Subi Subi
Operators
Operators are used to perform arithmetic and
loiHubal operations on data. They enable us to
manipulate and interpret data to produce useful
outputs.
The 5 main operator types in
Operators are represented by characters or
Python are:
special keywords.
● arithmetic operators
In general, Python’s operators follow the in-fix or
prefix notations.
● comparison operators
In-fix operators appear between two operands
(values on which the operator acts) and hence, ● assignment operators
are usually known as binary operators:
● loiHubal operators
A prefix operator usually works on one operand
and appears before it. Hence, prefix operators ● bitwise operators
are known as unary operators:
Subi Subi
Subi Subi
Arithmetic Operators
Below, we can find the basic arithmetic operators in order of precedence. The
operator listed higher will be computed first.
** Exponent In-fix
Subi Subi
Subi Subi
Addition
We can add two numbers using the + operator:
print(10 + 5)
float1 = 13.65
float2 = 3.40
print(float1 + float2)
num = 20
flt = 10.5
print(num + flt)
Python automatically converts the integer to a floating-point number. This applies to all
arithmetic operations.
Subi Subi
Subi Subi
Subtraction
We can subtract one number from the other using the - operator:
print(10 - 5)
float1 = -18.678
float2 = 3.55
print(float1 - float2)
num = 20
flt = 10.5
print(num - flt)
Subi Subi
Subi Subi
Multiplication
print(40 * 10)
float1 = 5.5
float2 = 4.5
print(float1 * float2)
print(10.2 * 3)
Subi Subi
Subi Subi
Division
print(40 / 10)
float1 = 5.5
float2 = 4.5
print(float1 / float2)
print(12.4 / 2)
Subi Subi
Subi Subi
Floor Division
In floor division, the result is floored to the nearest smaller integer. It is also
known as integer division.
print(43 // 10)
float1 = 5.5
float2 = 4.5
print(5.5 // 4.5)
print(12.4 // 2)
Unlike normal division, floor division between two integers results in an integer.
Subi Subi
Subi Subi
Modulo
A number’s modulo with another number can be found using
the % operator:
print(10 % 2)
twenty_eight = 28
print(twenty_eight % 10)
Subi Subi
Subi Subi
Precedence
An arithmetic expression containing different operators will be computed on
the basis of operator precedence.
# Different precedence
print(10 - 3 * 2) # Multiplication computed first, followed by subtraction
# Same precedence
print(3 * 20 / 5) # Multiplication computed first, followed by division
print(3 / 20 * 5) # Division computed first, followed by multiplication
Subi Subi
Subi Subi
Parentheses
Keep in mind that we are never restricted to these operators only, there are
countless more arithmetic utilities at our disposal.
Subi Subi
Subi Subi
Comparison Operators
== Equal To In-fix
Subi Subi
Subi Subi
Comparisons
The result of a comparison is always a bool.
Subi Subi
Subi Subi
num1 = 5
num2 = 10
num3 = 10
list1 = [6,7,8] As we can see in
list2 = [6,7,8] line 7, num2 is
indeed greater
print(num2 > num1) # 10 is greater than 5 than num1. Hence,
the result is True.
print(num1 > num2) # 5 is not greater than 10
On the other
hand, line 8
print(num2 == num3) # Both have the same value contains an
print(num3 != num1) # Both have different values incorrect
comparison, which
print(3 + 10 == 5 + 5) # Both are not equal results in False.
Subi Subi
Subi Subi
Assignment Operators
This is a category of operators which is used to assign values to a variable. The
= operator is an assignment operator, but not the only one.
= Assign In-fix
Subi Subi
Subi Subi
Subi Subi
Subi Subi
Assigning Values
Let’s go through a few examples to see how values are assigned to variables.
Subi Subi
Subi Subi
The Other Operators
Below, we can see some of the assignment operators we talked about in action:
num = 10
print(num)
num += 5
print(num)
num -= 5
print(num)
num *= 2
print(num)
num /= 2
print(num)
num **= 2
print(num)
Subi Subi
Subi Subi
LoiHubal Operators
or OR In-fix
Subi Subi
Subi Subi
LoiHubal Expressions
# OR Expression
my_bool = True or False
print(my_bool)
# AND Expression
my_bool = True and False
print(my_bool)
# NOT expression
my_bool = False
print(not my_bool)
Subi Subi
Subi Subi
Bit Value
print(10 * True)
print(10 * False)
Output : 0 30 30 -11 80 2
Subi Subi
Subi Subi
Explanation
In line 4, we perform the bitwise AND. This operation takes a bit from num1 and
the corresponding bit from num2 and performs an AND between them.
At the first step, the first binary digits of both numbers are taken:
01010
These two will once again give us 0.
10100
Doing this for all pairs, we can see that the answer is 0 each time.
The OR operation in line 5 will work in the same principle except that instead of
multiplication, we will perform addition between the two binary numbers.
0 OR 1 gives us 1. 1 OR 1 also produces 1 (binary numbers do not go beyond 1). However, 0
OR 0 will give us 0 (0 + 0 is still 0).
Bitwise XOR and NOT will work on each bit as well. You can play with the code to get a
better idea.
The bitshift operations (>> and <<) simply move the bits to either the right or the left.
When a binary number is shifted, a 0 also enters at the opposite end to keep the number
of the same size.
Let’s suppose we have a binary number 0110 (6 in Similarly, we can move 0110 twice to the left
decimal). The operation we perform is 0110 >> 2: with the following operation 0110 << 2:
Note: In Python, leading zeros are truncated. For example, the number 0011 will be the same
as 11. Similarly, the number 0001011 will be the same as 1011.
Subi Subi
Subi Subi
String Operations
Comparison Operators
Strings are compatible with the comparison operators. Each character has a Unicode
value.This allows strings to be compared on the basis of their Unicode values.
When two strings have different lengths, the string which comes first in the dictionary is
said to have the smaller value.
Let’s look at a few examples:
print('a' < 'b') # 'a' has a smaller Unicode value
Subi Subi
Subi Subi
Concatenation
The + operator can be used to merge two strings together:
first_half = "Bat"
The * operator allows us to multiply a string,
second_half = "man"
resulting in a repeating pattern:
full_name = first_half + second_half
print("ha" * 3) Output:
print(full_name)
Output: hahaha
Batman
Search
The in keyword can be used to check if a particular substring exists in another string. If the substring
is found, the operation returns true.
Subi Subi
Subi Subi
Grouping Values
In Python, we can store multiple values together in a single variable.
While there are many ways of doing so, the most popular is the list.It
is very similar to a string since a string is a collection of characters.
A list is also just a collection of values. However, the values can be of
any type. All we have to do is enclose all the elements in square
brackets, [], and separate them with commas.
Subi Subi
Subi Subi
Exercise: Gravitational Force
Gravitational force is the attractive force that exists between two
masses. It can be calculated by using the following formula:
GMm⁄r²
All the values have already been given to you. You must write the
formula in Pythonic syntax and store the answer in the grav_force
variable.
The parentheses in the grav_force formula are only there to make the
code more readable by separating the upper and lower parts of the
fraction. They are optional in this case (parentheses can have an effect
depending on the equation).
Subi Subi
Subi Subi
Conditional
Statements
Subi Subi
Subi Subi
What are Conditional Statements?
A conditional statement is a Boolean expression that, if True, executes a piece
of code.
Subi Subi
Subi Subi
The if Statement
The simplest conditional statement that we can write is the if statement. It
comprises of two parts:
The condition
The code to be executed
Subi Subi
Subi Subi
The Flow of an if Statement
An if statement runs like this:
if the condition holds True, execute the code to be executed. Otherwise, skip it
and move on.
num = 5
if (num == 5): # The condition is true
Output:
print("The number is equal to 5") # The code is executed
if num > 5: # The condtion is false
The number is equal to 5
print("The number is greater than 5") # The code is not executed
Our first condition simply checks whether the value of num is 5. Since this
Boolean expression returns True, the compiler goes ahead and executes the
print statement on line 4.
As we can see, the print command inside the body of the if statement is
indented to the right. If it wasn’t, there would be an error. Python puts a lot of
emphasis on proper indentation.
Subi Subi
Subi Subi
Conditions with LoiHubal Operators
We can use loiHubal operators to create more complex conditions in the if
statement. For example, we may want to satisfy multiple clauses for the
expression to be True.
num = 12
if num % 2 == 0 and num % 3 == 0 and num % 4 == 0:
# Only works when num is a multiple of 2, 3, and 4 Output:
print("The number is a multiple of 2, 3, and 4") The number is a multiple of 2, 3, and 4
if (num % 5 == 0 or num % 6 == 0): The number is a multiple of 5 and/or 6
# Only works when num is either a multiple of 5 or 6
print("The number is a multiple of 5 and/or 6")
In the first if statement, all the conditions have to be fulfilled since we’re using
the and operator.
Subi Subi
Subi Subi
Nested if Statements
A cool feature of conditional statements is that we can nest them. This means
that there could be an if statement inside another!
Hence, we can use nesting to make complex conditions in our program:
num = 63 Output:
if num >= 0 and num <= 100:
The number is in the 60-70
if num >= 50 and num <= 75:
range
if num >= 60 and num <= 70:
print("The number is in the 60-70 range")
There’s nothing too tricky going on here. If the condition turns out
to be False, the code after the else: keyword is executed.
Hence, we can now perform two different actions based on the
condition’s value.
The else keyword will be on the same indentation level as the if
keyword. Its body will be indented one tab to the right just like the if
statement.
Here’s the if-else statement in action:
num = 60
if num <= 50:
print("The number is less than or equal to 50")
Output:
else:
The number is greater than 50
print("The number is greater than 50")
Subi Subi
Subi Subi
Benefits of if-else
The example above could also be written with two if conditions:
num = 60
if num <= 50:
print("The number is less than or equal to 50")
if num > 50:
print("The number is greater than 50")
However, for the second if, we have to specify the condition again.
This can be tricky when dealing with complex conditions. The else
statement automatically handles all the situations when the if fails.
Do keep in mind that the else statement cannot exist on its own. It is
merely a counterpart of the if statement. It can still contain its own
nested if or if-else statements. We’ll leave that as an exercise for you
to try on your own.
Subi Subi
Subi Subi
Conditional Expressions
Conditional expressions use the functionality of an if-else statement in a
different way.
num = 60
Output:
output = "The number is less than or equal to 50" \
if num <= 50 else "The number is greater than 50" The number is greater than 50
print(output)
Please note that the backslash \ in the above code is only a line continuation character that can
be used to split a single line into multiple lines.
Subi Subi
Subi Subi
The if-elif-else Statement
The if-else statement handles two sides of the same condition: True
and False. This works very well if we’re working with a problem that
only has two outcomes.
However, in programming, it isn’t always a True or False scenario,
and a problem can have multiple outcomes.
This is where the if-elif-else statement shines. It is the most comprehensive
conditional statement because it allows us to create multiple conditions easily.
The elif stands for else if, indicating that if the previous condition fails, try this one.
Let’s write an if-elif-else statement which checks the state of a traffic signal and
generates the appropriate response:
light = "Red"
if light == "Green":
print("Go")
elif light == "Yellow":
Output
print("Caution")
Stop
elif light == "Red":
print("Stop")
else:
print("Incorrect light signal")
Subi Subi
Subi Subi
Multiple elif Statements#
This is the beauty of the if-elif-else statement. We can have as many
elifs as we require, as long as they come between if and else.
Note: An if-elif statement can exist on its own without an else block
at the end. However, an elif cannot exist without an if statement
preceding it (which naturally makes sense).
Let’s write a piece of code that checks whether the value of an integer is in the
range of 0-9 and prints the word in English:
num = 5
elif num == 5:
if num == 0:
print("Five")
print("Zero")
elif num == 6:
elif num == 1:
print("Six") Output:
print("One")
elif num == 7:
elif num == 2: Five
print("Seven")
print("Two")
elif num == 8:
elif num == 3:
print("Eight")
print("Three")
elif num == 9:
elif num == 4:
print("Nine")
print("Four")
Subi Subi
Subi Subi
An important thing to keep in mind is that an if-elif-else or if-elif statement is not the
same as multiple if statements. if statements act independently. If the conditions of
two successive ifs are True, both statements will be executed. On the other hand, in
if-elif-else, when a condition evaluates to True, the rest of the statement’s conditions
are not evaluated.
num = 10 num = 10
if num > 5: if num > 5:
print("The number is greater print("The number is greater than 5")
than 5") elif num % 2 == 0:
if num % 2 == 0: print("The number is even")
print("The number is even") else:
if not num % 2 == 0: print("The number is odd and less than or equal to 5")
print("The number is odd")
Output Output
The number is greater than 5 The number is greater than 5
The number is even
As we can see, in the if tab, all the statements are computed one by one. Hence, we get multiple outputs.
In the if-elif-else tab, since the first condition holds true, all the others are discarded. This proves to be
more efficient in terms of code performance.
Subi Subi
Subi Subi
Exercise: Discounted Price
In this challenge, you must discount a price according to its value.
Sample Input
price = 250
Sample Output
price = 200
Subi Subi
Subi Subi
Solution Review: Discounted Price
To handle all the cases, we’ll use an if-elif statement.
Notice that we only need to specify the lower bound
in each condition. This is because, for every
price = 250
condition, the upper bound is already being
checked in the previous condition. if price >= 300:
price *= 0.7 # (1 - 0.3)
The program will only go into the first elif if the price
elif price >= 200:
is lower than 300.
price *= 0.8 # (1 - 0.2)
This sort of smart structuring in a conditional elif price >= 100:
statement can be very useful when dealing with a price *= 0.9 # (1 - 0.1)
large number of complex cases.
elif price < 100 and price >= 0:
The price after a discount would be price * (1 - price *= 0.95 # (1 - 0.05)
discount). print(price)
Subi Subi
Subi Subi
Functions
Subi Subi
Subi Subi
What are Functions?
A function is a reusable set of operations.
That sounds like a pretty straightforward definition. But what does it exactly mean?
Take the print() and len() statements for instance. Both always perform predefined tasks.
Hence, they are examples of functions!
Subi Subi
Subi Subi
For every new pair of integers, we need to write the if-else statement again.
All this could become much simpler if we had a function to perform the steps
necessary for calculating the minimum.
The good news is that Python already has the min() function:
Subi Subi
Subi Subi
Types of Functions in Python
Functions are perhaps the most commonly used
feature of Python. There are two basic types of
functions in Python:
○ Built-in functions
○ User-defined functions
Subi Subi
Subi Subi
Function Creation
Components of a Function
The function name is simply the name we’ll use to identify the function.
The parameters of a function are the inputs for that function. We can use these
inputs within the function. Parameters are optional.
The body of the function contains the set of operations that the function will
perform. This is always indented to the right.
Subi Subi
Subi Subi
Implementation
Let’s start by making a plain function that prints four lines of text. It won’t
have any parameters. We’ll name it my_print_function. We can call the
function in our code using its name along with empty parentheses:
def my_print_function(): # No parameters
print("This")
print("is")
print("A")
print("function")
# Function ended
Subi Subi
Subi Subi
Function Parameters
They are the means of passing data to the function. This data can be used by
the function to perform a meaningful task.
When creating a function, we must define the number of parameters and their
names. These names are only relevant to the function and won’t affect variable
names elsewhere in the code. Parameters are enclosed in parentheses and
separated by commas.
The min() function requires two numbers as inputs and prints the smaller one.
Let’s define our own basic form of the min() function that simply prints the
minimum. We’ll name it minimum():
Subi Subi
Subi Subi
minimum(num1, num2)
Subi Subi
Subi Subi
The return Statement
So far, we’ve only defined functions that print something. They don’t return
anything back to us. But if we think back, functions return values all the time.
Just take len() for example. It returns an integer which is the length of the data
structure.
To return something from a function, we must use the return keyword. Keep in
mind that once the return statement is executed, the compiler ends the
function. Any remaining lines of code after the return statement will not be
executed.
Let’s refactor the minimum() method to return the smaller value instead of
printing it. Now, it’ll work just like the built-in min() function with two parameters:
Subi Subi
Subi Subi
def minimum(first, second):
if (first < second):
return first
return second
num1 = 10
num2 = 20
result = minimum(num1, num2) # Storing the value returned by the function
print(result)
It is a good practice to define all our functions first and then begin the main
code. Defining them first ensures that they can be used anywhere in the
program safely.
Subi Subi
Subi Subi
Function Scope
The scope of a function means the extent to which the variables and other data
items made inside the function are accessible in code.
Whenever a function runs, the program moves into the function scope. It moves
back to the outer scope once the function has ended.
Data Lifecycle
In Python, data created inside the function cannot be used from the outside
unless it is being returned from the function.
Variables in a function are isolated from the rest of the program. When the
function ends, they are released from memory and cannot be recovered.
Subi Subi
Subi Subi
def func():
name = "Stark"
func()
print(name) # Accessing 'name' outside the function
As we can see, the name variable doesn’t exist in the outer scope, and Python
lets us know.
Similarly, the function cannot access data outside its scope unless the data
has been passed in as an argument.
Subi Subi
Subi Subi
As we can see, the name variable doesn’t exist in the outer scope, and Python
lets us know.
Similarly, the function cannot access data outside its scope unless the data
has been passed in as an argument.
name = "Ned"
def func():
name = "Stark"
func()
print(name) # The value of 'name' remains unchanged.
Subi Subi
Subi Subi
Altering Data
When mutable data is passed to a function, the function can modify or alter it.
These modifications will stay in effect outside the function scope as well. An
example of mutable data is a list.
In the case of immutable data, the function can modify it, but the data will
remain unchanged outside the function’s scope. Examples of immutable data
are numbers, strings, etc.
num = 20
def multiply_by_10(n):
n *= 10
num = n # Changing the value inside the function
print("Value of num inside function:", num)
return n
multiply_by_10(num)
print("Value of num outside function:", num) # The original value remains unchanged
Subi Subi
Subi So, it’s confirmed that immutable objects are unaffected by the working of a Subi
function. If we really need to update immutable variables through a function, we
can simply assign the returning value from the function to the variable.
We passed num_list to our function as the my_list parameter. Now, any changes
made to my_list will reflect in num_list outside the function. This would not
happen in the case of an immutable variable.
And trust us when we say that there’s something for almost everyone.
Strings
Functions that are properties of a particular entity are known as
methods. These methods can be accessed using the . operator. The string
data type has several methods associated with it. Let’s look at some of
them.
Search
An alternative for finding a substring using the in keyword is the find()
method. It returns the first index at which a substring occurs in a string. If
no instance of the substring is found, the method returns -1.
Subi Subi
Subi Subi
Replace
The replace() method can be used to replace a part of a string
with another string. Here’s the template we must use:
a_string.replace(substring_to_be_replaced, new_string)
The original string is not altered. Instead, a new string with the
replaced substring is returned.
Output:
a_string = "Welcome to iHub!"
new_string = a_string.replace("Welcome to", Welcome to iHub!
"Greetings from")
Greetings from iHub!
print(a_string)
print(new_string)
Subi Subi
Subi Subi
Changing the Letter Case#
In Python, the letter case of a string can be easily
changed using the upper() and lower() methods.
print("UpperCase".upper()) Output:
print("LowerCase".lower()) UPPERCASE
lowercase
Subi Subi
Subi Subi
Joining strings
With join() method you can join multiple strings.
a>>b>>c
a<<b<<c
a, b, c
Over here, the string.join(llist) returns a single string, with the elements of the
llist separated by string.
Subi Subi
Subi Subi
Formatting
The format() method can be used to format the specified
value(s) and insert them in string’s placeholder(s). Let’s
try it out:
string1 = "Learn Python {version} at
{cname}".format(version = 3, cname = "iHub")
string2 = "Learn Python {0} at {1}".format(3, "iHub")
string3 = "Learn Python {} at {}".format(3, "iHub")
Output:
print(string1) Learn Python 3 at iHub
print(string2) Learn Python 3 at iHub
print(string3)
Learn Python 3 at iHub
The placeholders can be identified using named indexes {cname}, numbered indexes {0}, or even empty
placeholders {}.
Subi Subi
Subi Subi
Type Conversions
int()
To convert data into an integer, we can use the int() utility.
Subi Subi
Subi Subi
ord()
This function can be used to convert a character to its Unicode value:
Output:
print(ord('a'))
print(ord('0')) 97
48
float()
The float() function translates data into a floating-point number:
print(float(24)) Output:
print(float('24.5'))
24.0
print(float(True)) 24.5
1.0
Subi Subi
Subi Subi
str()
To convert data into a string, we must use str():
Output
print(str(12) + '.345')
12.345
print(str(False))
print(str(12.345) + ' is a string') False
12.345 is a string
bool()
This function takes in data and gives us the corresponding Boolean value.
Strings are always converted to True, except if the string is empty. Floats and
integers with a value of zero are considered to be False in Boolean terms:
Subi Subi
Subi Subi
Input From the User
The input() function
In Python, input() function is used to take input from user.
The input is automatically converted to string. If you enter a number, it will also
be converted to a string.
Subi Subi
Subi Subi
Lambdas
We have to specify function names while creating them. However, there is a
special class of functions for which we do not need to specify function names.
Definition
Lambdas are defined using the lambda keyword. Since they return data, it is a
good practice to assign them to a variable.
Syntax
Below, we can find a lambda that triples the value of the parameter and returns
this new value:
Subi Subi
Subi Subi
triple = lambda num : num * 3 # Assigning the lambda to a variable
Output
print(triple(10)) # Calling the lambda and giving it a parameter 30
As we can see, lambdas are simpler and more readable than normal
functions. But this simplicity comes with a limitation.
Why don’t we just pass a lambda as the argument? The four operations are
pretty simple, so they can be written as lambdas.
Subi Subi
Subi Subi
More Examples
The built-in map() function creates a map object using an existing list and a
function as its parameters. This object can be converted to a list using the list()
function.
map(function, list)
The function will be applied, or mapped, to all the elements of the list.
Subi Subi
Subi Subi
We could have created a function that doubles a number and used it as the
argument in map(), but the lambda made things simpler.
Another similar example is the filter() function. It requires a function and a list.
filter() filters elements from a list if the elements satisfy the condition that is
specified in the argument function.
Let’s write a filter() function that filters all the elements which are greater than
10:
just like map(), filter() returns a new object without changing the original list.
Subi Subi
Subi Subi
Recursion
Recursion is the process in
which a function calls itself
during its execution. Each
recursive call takes the
program one scope deeper
into the function.
The recursive calls stop at the
base case. The base case is a
check used to indicate that
there should be no further
recursion.
Imagine recursive calls as
nested boxes where each box
represents a function call.
Each call makes a new box.
When the base case is
reached, we start moving out
of the boxes one by one:
Subi Subi
Subi Subi
A Simple Example
Let’s write a function which decrements a number recursively until the number
becomes 0: Output
def rec_count(number): 5
print(number) 4
# Base case 3
if number == 0:
2
return 0
rec_count(number - 1) # A recursive call with a different argument 1
print(number) 0
rec_count(5)
1
This is fairly easy to understand. In each call, the value of the number variable is 2
printed. We then check whether the base case has been fulfilled. If not, we make a
recursive call to the function with the current value decremented. 3
One thing to notice is that an outer call cannot move forward until all the inner 4
recursive calls have finished. This is why we get a sequence of 5 to 0 to 5. 5
Subi Subi
Subi Subi
Why Use Recursion?
Recursion is a concept which many find difficult to grasp at
first, but it has its advantages. For starters, it can
significantly reduce the runtime of certain algorithms, which
makes the code more efficient.
Subi Subi
Subi Subi
A Complex Example
The Fibonacci sequence is a popular series of numbers in mathematics, where
every number is the sum of the two numbers before it. The first two terms in the
series are 0 and 1:
0 1 1 2 3 5 8 13
Let’s write a function which takes in a number, def fib(n):
n, and returns the nth number in the Fibonacci # The base cases
sequence. It is important to note that for the
if n <= 1: # First number in the sequence
following example, we will be treating all inputs
less than 1 as incorrect and therefore, our input return 0
will start from 1. So, if n == 6, the function will elif n == 2: # Second number in the sequence
return 5:
return 1
First, we handle our base cases. We know that else:
the first two values are always 0 and 1, so that is # Recursive call
where we can stop our recursive calls.
return fib(n - 1) + fib(n - 2)
If n is larger than 2, then it will be the sum of print(fib(6)) Output
the two values before it.
Subi
5
Subi
Subi Subi
Exercise: Repetition and Concatenation
Problem Statement
In this exercise, you must implement the rep_cat function. You are given two
integers, x and y, as arguments. You must convert them into strings. The string
value of x must be repeated 10 times and the string value of y must be repeated
5 times.
At the end, y will be concatenated to x and the resulting string must returned.
Sample Input
x=3
y=4
Sample Output
'333333333344444'
Subi Subi
Subi Subi
Coding Challenge
Take some time to figure out the loiHub behind this problem before jumping to
the implementation. The function skeleton has been created. You only need to
write code in its body.
The pass statement can be erased and replaced with your return statement.
If you get stuck, feel free to check out the solution review in the next lesson.
Good luck!
def rep_cat(x, y):
# Write your code here
pass
Subi Subi
Subi Subi
Solution Review: Repetition and
Concatenation
Explanation
def rep_cat(x, y):
To convert the integers into strings, we
return str(x) * 10 + str(y) * 5
can use the str() method.
The factorial of a number, n, is its product with all the integers between 0
and n.
Subi Subi
Subi Subi
Sample Input n=5
The input will always be an integer, so you don’t need to worry about that.
If the integer is negative, the function always returns -1.
If you feel stuck, feel free to check out the solution review in the next
lesson.
Good luck!
def factorial(n):
pass # Replace with your own code
Subi Subi
Subi Subi
Solution Review: The Factorial!
Explanation
This problem can easily be solved using recursion.
def factorial(n):
The base case is when n is 1 or 0 since it’s the
# Base case
minimum we can go. In either case, we return 1, since
if n == 0 or n == 1:
it is the factorial for both these values.
return 1
if n < 0: Other than that, the only special case is if n is
return -1 negative. That can be handled with a simple if
# Recursive call statement.
return n * factorial(n - 1)
The final and most important step is the recursive
print(factorial(5)) call. Each call returns a product back to the
previous call where the product is multiplied with the
current value of n in that particular call.
Subi Subi
Subi Subi
Loops
Subi Subi
Subi Subi
What are Loops?
Definition
A loop is a control structure that is used to perform a set of
instructions for a specific number of times.
The iterator starts from the beginning of the sequence. In each iteration, the
iterator updates to the next value in the sequence.
Structure
The loop always begins with the for keyword. The body of the loop is indented to
the right:
The in keyword specifies that the iterator will go through the values in the
sequence/data structure.
Subi Subi
Subi Subi
Looping Through a Range
In Python, the built-in range() function can be used to create a sequence of
integers. This sequence can be iterated over through a loop. A range is
specified in the following format
range(START, END, STEP):
The end value is not included in the list.
The step decides the number of steps the iterator jumps ahead after each
iteration. It is optional and if we don’t specify it, the default step is 1, which
means that the iterator will move forward by one step after each iteration.
Let’s take a look at how a for loop iterates through a range of integers::
OUTPUT:
for i in range(1, 11): # A sequence from 1 to 10
if i % 2 == 0: 1 is odd 6 is even
print(i, " is even") 2 is even 7 is odd
else: 3 is odd 8 is even
4 is even 9 is odd
print(i, " is odd") 5 is odd 10 is even
Subi Subi
Subi Subi
Subi Subi
Subi Subi
Looping Through a List/String
A list or string can be iterated through its indices.
OUTPUT:
[2.5, 16.42, 10.77, 8.3, 34.21]
[5.0, 32.84, 21.54, 16.6, 68.42]
Subi Subi
Subi Subi
for num in float_list: # Iterator traverses to the last index of the list
if num > 10:
count_greater += 1 Output
print(count_greater)
3
In this example, num is the iterator. An important thing to keep in mind
is that in the case above, altering num will not alter the actual value in
the list. The iterator makes a copy of the list element.
Subi Subi
Subi Subi
Nested for Loops
Execution of Nested Loops
The simplest way would be to compare every element with the rest of the
list. A nested for loop is perfect for this:
n = 50
num_list = [10, 25, 4, 23, 6, 18, 27, 47]
for n1 in num_list: Output
for n2 in num_list: # Now we have two iterators 23 27
if(n1 != n2):
27 23
if(n1 + n2 == n):
print(n1, n2)
In the code above, each element is compared with every other element to
check if n1 + n2 is equal to n. This is the power of nested loops!
Subi Subi
Subi Subi
The break Keyword
Sometimes, we need to exit the loop before it reaches the end. This can happen if we
have found what we were looking for and don’t need to make any more computations in
the loop. A perfect example is the one we have just covered. At a certain point, n1 is 23
and n2 is 27. Our condition of n1 + n2 == n has been fulfilled. But the loops keep running
and comparing all other pairs as well. This is why the pair is printed twice. It would be
nice to just stop it when the pair is found once. That’s what the break keyword is for. It
n = 50 can break the loop whenever we want. Let’s add it to the example above:
num_list = [10, 25, 4, 23, 6, 18, 27, 47]
As we can see, only (23, 27)
found = False # This bool will become true once a pair is found
for n1 in num_list:
is printed this time.
for n2 in num_list: This is because (23, 27) is
Output
if(n1 != n2): the first pair which
if(n1 + n2 == n): 23 satisfies the condition. We
found = True # Set found to True
27 terminate the loop after
break # Break inner loop if a pair is found
that using the found bool.
if found:
Hence, (27, 23) is never
print(n1, n2) # Print the pair
computed.
break # Break outer loop if a pair is found
Subi Subi
Subi Subi
The continue Keyword
When the continue keyword is used, the rest of that particular
iteration is skipped. The loop continues on to the next iteration. We
can say that it doesn’t break the loop, but it skips all the code in the
current iteration and moves to the next one. We don’t need to get
into too much detail, so here’s a simple example:
num_list = list(range(0, 10)) 0
for num in num_list: 1
if num == 3 or num == 6 or num == 8: 2
continue 4
print(num) 5
7
The loop goes into the if block when num is 3, 6, or 8. When this
9
happens, continue is executed and the rest of the iteration, including
the print() statement, is skipped.
Subi Subi
Subi Subi
The pass Keyword
In all practical meaning, the pass statement does
nothing to the code execution. It can be used to
represent an area of code that needs to be written.
Hence, it is simply there to assist you when you haven’t
written a piece of code but still need your entire program
to execute.
print(len(num_list))
Subi Subi
Subi Subi
The while Loop
The while loop keeps iterating over a certain set of operations as long as a
certain condition holds True.
Structure
In a for loop, the number of iterations is fixed since we know the size of the
sequence.
On the other hand, a while loop is not always restricted to a fixed range. Its
execution is based solely on the condition associated with it.
Subi Subi
Subi Subi
The while Loop in Action
Here’s a while loop that finds out the maximum power of n before the value
exceeds 1000:
n = 2 # Could be any number
power = 0
val = n
while val < 1000:
power += 1
Output
val *= n
print(power) 9
In each iteration, we update val and check if its value is less than 1000. The
value of power tells us the maximum power n can have before it becomes
greater than or equal to 1000. Think of it as a counter.
Subi Subi
Subi Subi
We can also use while loops with data structures, especially in cases where the
length of data structure changes during iterations.
The following loop computes the sum of the first and the last digits of any
integer:
n = 249
Output
last = n % 10 # Finding the last number is easy
first = n # Set it to `n` initially 11
while first >= 10:
first //= 10 # Keep dividing by 10 until the leftmost digit is reached.
result = first + last
print(result)
Subi Subi
Subi Subi
Cautionary Measures
Compared to for loops, we should be more careful when creating while loops.
This is because a while loop has the potential to never end. This could crash a
program!
while(True): The loops beside will never end because their conditions
print("Hello World") always remain true. Hence, we should always make sure that our
condition has a mutable variable/object that is being updated in the
x=1
loop and will eventually turn the condition false.
while(x > 0):
x += 5
Other Properties
The break, continue, and pass keywords work with while loops.
Like for loops, we can also nest while loops. Furthermore, we can nest the two
types of loops with each other.
Subi Subi
Subi Subi
Iteration vs. Recursion
If we observe closely, there are several similarities
between iteration and recursion. In recursion, a function
performs the same set of operations repeatedly but with
different arguments.
A loop does the same thing except that the value of the
iterator and other variables in the loop’s body change in
each iteration.
You will write your code in the check_balance() function, which returns
True if the brackets are balanced and False if they are not.
For the sake of simplicity, you can assume that the string will not
contain any other characters.
Subi Subi
Subi Subi
Solution Review: Balanced Brackets
The solution relies on the value of the check variable,
which is updated in each iteration. If an opening
bracket is found, check is incremented by 1. In the
def check_balance(brackets): case of a closing bracket, check is decremented by 1.
check = 0
The loiHub is that check should never be negative
for bracket in brackets:
because that would imply that somewhere in the
if bracket == '[':
check += 1
string, there are more closing brackets than opening
elif bracket == ']':
ones. The condition for being unbalanced is satisfied
check -= 1
and we don’t need to check further.
if check < 0: Another case is that after the loop finishes, the value
break of check would be 0 because the brackets match. If
return check == 0 it’s not, the function simply returns False.
bracket_string = '[[[[]]'
print(check_balance(bracket_string))
Subi Subi
Subi Subi
Exercise: A Sum of Zero
Problem Statement
You must implement the check_sum() function which takes in a list and returns
True if the sum of two numbers in the list is zero. If no such pair exists, return
False.
Sample Input
[10, -14, 26, 5, -3, 13, -5]
Sample Output
True
Subi Subi
Subi Subi
Solution Review: A Sum of Zero
def check_sum(num_list):
for first_num in range(len(num_list)):
for second_num in range(first_num + 1, len(num_list)):
if num_list[first_num] + num_list[second_num] == 0:
return True
We can use a nested for loop to
return False obtain all the possible pairs in the
num_list = [10, -14, 26, 5, -3, 13, -5] list.
print(check_sum(num_list)) By using range(), we can make sure
that the inner loop always starts
one index ahead of the outer loop.
0 1 1 2 3 5 8 13
You must write the fib() function which takes in a positive integer, n, and returns
the n-th Fibonacci number. However, instead of using recursion, your function
must use any of the loops. (If n is negative or zero, return -1.)
Sample Input
n=7
Sample Output
8
Subi Subi
Subi Subi
def fib(n):
Solution Review: Fibonacci Series
# The first and second values will always be fixed
first = 0
second = 1
if n < 1:
return -1
if n == 1:
return first
if n == 2:
return second
count = 3 # Starting from 3 because we already know the first two values
while count <= n:
fib_n = first + second
first = second
second = fib_n
count += 1 # Increment count in each iteration
return fib_n
n=7
print(fib(n))
Subi Subi
Subi Subi
Data Structures
Subi Subi
Subi Subi
What are Data Structures?
A data structure is a way of storing and organizing data
according to a certain format or structure.
Subi Subi
Subi Subi
Data Structures in Python
Python is equipped with several built-in
data structures to help us efficiently
handle large amounts of data.
The four primary built-in data
structures offered in Python3 are:
- List
- Tuple
- Dictionary
- Set
Subi Subi
Subi Subi
Lists
The list is perhaps the most commonly used data structure in Python. It
allows us to store elements of different data types in one container.
Lists are ordered, like strings. Elements are stored linearly at a specific
index.
We can see from the illustration above that a list bears resemblance to a
string.
The beauty of lists lies in the fact that we are not bound to one type
of data.
Subi Subi
Subi Lists are mutable, which further expands their functionality: Subi
Each level of indexing takes us one step deeper into the list, allowing us to
access any element in a complex list.
Subi Subi
Subi Subi
Merging Lists
Python makes it really easy to merge lists together. The simplest way is to use
the + operator just like strings:
part_A = [1, 2, 3, 4, 5]
part_B = [6, 7, 8, 9, 10] Output
merged_list = part_A + part_B [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(merged_list)
Alternatively, we could use the extend() property of a list to add the elements of
one list at the end of another:
part_A = [1, 2, 3, 4, 5]
part_B = [6, 7, 8, 9, 10]
Output
part_A.extend(part_B) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(part_A)
Subi Subi
Subi Subi
Common List Operations
Adding Elements
All the elements of a list cannot always be specified beforehand and there’s a
strong possibility that we’ll want to add more elements during runtime.
The append() method can be used to add a new element at the end of a list. The
following template must be followed:
aList.insert(index, newElement)
If a value already exists at that index, the whole list from that
value onwards will be shifted one step to the right:
Output
num_list = [1, 2, 3, 5, 6]
num_list.insert(3, 4) # Inserting 4 at the 3rd index. 5 and 6
shifted ahead [1, 2, 3, 4,
print(num_list) 5, 6]
Subi Subi
Subi Subi
Removing Elements
Deleting elements is as easy as adding them. The counterpart of append() is the
pop() operation which removes the last element from the list.
If we need to delete a particular value from a list, we can use the remove()
method by following this template:
aList.remove(element_to_be_deleted)
Subi Subi
Subi houses = ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"] Subi
print(houses)
houses.remove("Ravenclaw")
print(houses)
Subi Subi
Subi If we just want to verify the existence of an element in a list, we can use the in Subi
operator:
Output
cities = ["London", "Paris", "Los Angeles", "Beirut"]
print("London" in cities) True
print("Moscow" not in cities)
True
List Sort
A list can be sorted in ascending order using the sort() method. Sorting can be
done alphabetically or numerically depending on the content of the list:
Subi Subi
Subi Subi
List Comprehension
List comprehension is a technique that uses a for loop and a condition to
create a new list from an existing one.
The result is always a new list, so it’s a good practice to assign list
comprehension to a new variable.
● The for loop will iterate an existing list. The iterator will be used in the
expression.
● New elements will only be added to the new list when the if condition is
fulfilled. This component is optional.
Subi Subi
Subi Subi
Creating a List Comprehension
Let’s create a new list whose values are the doubles of the values of an existing
list.
Let’s break down the loop above into the three components of a list
comprehension.
The expression is equivalent to n * 2 since it’s used to create each value in the
new list.
The contents of a tuple are enclosed in parentheses, (). They are also ordered,
and hence, follow the linear index notation.
Subi Subi
Subi Subi
Merging Tuples
Tuples can be merged using the + operator:
Output
hero1 = ("Batman", "Bruce Wayne") ('Batman', 'Bruce Wayne', 'Wonder
hero2 = ("Wonder Woman", "Diana Prince") Woman', 'Diana Prince')
awesome_team = hero1 + hero2
print(awesome_team)
Nested Tuples
In the previous coding example, instead of merging the two tuples, we could create a new tuple with
these two tuples as its members:
Subi Subi
Subi Subi
Search
We can check whether an element exists in a tuple by using the in operator as
follows:
Since tuples are immutable, we can’t add or delete elements from them.
Furthermore, it isn’t possible to append another tuple to an existing tuple.
Subi Subi
Subi Subi
Dictionaries
Compared to a list or tuple, a dictionary has a slightly more complex structure.
key:value
Subi Subi
Subi Subi
Creating a Dictionary
Let’s create an empty dictionary and a simple phone_book using the dictionary
data structure:
Output
empty_dict = {} # Empty dictionary
print(empty_dict) {}
{'Batman': 468426, 'Ghostbusters': 44678, 'Cersei':
phone_book = {"Batman": 468426, 237734}
"Cersei": 237734,
"Ghostbusters": 44678}
print(phone_book)
Note: Since the dictionary is an unordered data structure, the order of the output will not
necessarily match the order in which we wrote the entries. Key-value pairs are accessed in a
random or unordered manner.
The dictionary above could also be written in the same line. Dividing it into lines, only increases
readability.
Subi Subi
Subi Subi
The dict() Constructor
As the name suggests, the dict() empty_dict = dict() # Empty dictionary
constructor can be used to print(empty_dict)
construct a dictionary. Think of
the “constructor” as an operation phone_book = dict(Batman=468426,
that gives us a dictionary. If our Cersei=237734, Ghostbusters=44678)
keys are simple strings without
# Keys will automatically be converted to
special characters, we can create
strings
entries in the constructor. In that
case, values will be assigned to print(phone_book)
keys using the = operator. A
popular practice is to create an # Alternative approach
empty dictionary and add entries phone_book = dict([('Batman', 468426),
later.Let’s refactor the empty_dict ('Cersei', 237734),
and phone_book examples to ('Ghostbusters', 44678)])
make them work with dict(): print(phone_book)
Subi Subi
Subi Subi
Accessing Values
The keys and values can have any of the basic data types or structures.
Two keys can have the same value. However, it is crucial that all keys are unique.
We can see from the phone_book example how dictionaries can organize data in a meaningful way. It is
easy to tell a character’s phone number because the pair is stored together.
For many, this is where a dictionary has an edge over a list or a tuple. Since there are no linear indices,
we do not need to keep track of where values are stored.
Instead, we can access a value by enclosing its key in square brackets, []. This is more meaningful than
the integer indices we use for tuples and lists.
Output
{'Cersei': 237734, 'Batman': 468426, 'Ghostbusters': 44678}
{'Cersei': 237734, 'Batman': 468426, 'Godzilla': 46394, 'Ghostbusters': 44678}
{'Cersei': 237734, 'Batman': 468426, 'Godzilla': 9000, 'Ghostbusters': 44678}
Subi Subi
Subi Subi
Removing Entries
To delete an entry, we can use the del keyword:
Output
{'Ghostbusters': 44678, 'Cersei': 237734, 'Batman': 468426}
{'Ghostbusters': 44678, 'Cersei': 237734}
Subi Subi
Subi Subi
If we want to use the deleted value, the pop() or popitem() methods would work
better:
However, to iterate the dictionary, we’ll use the dict.items() operation which turns a dictionary into a list
of (key, value) tuples. Here’s a simple example where the keys of the original dictionary are squared and
'!' is appended to each string value:
Output
{1: 'Gryffindor', 2: 'Slytherin', 3: 'Hufflepuff', 4: 'Ravenclaw'}
{16: 'Ravenclaw!', 1: 'Gryffindor!', 4: 'Slytherin!', 9: 'Hufflepuff!'}
Subi Subi
Subi Subi
Sets
A set is an unordered collection of data items.
The data is not indexed, so we can’t access elements using indices or get().
This is perhaps the simplest data structure in Python. We can think of it as a bag containing
random items.
Subi Subi
Subi Subi
Creating a Set
The contents of a set are encapsulated in curly brackets, {}. Like all data
structures, the length of a set can be calculated using len():
Output
random_set = {"iHub", 1408, 3.142,(True, False)}
print(random_set) {1408, (True, False),
print(len(random_set)) # Length of the set 3.142, ‘iHub’}
4
The set() Constructor
The set() constructor is an alternate way of creating sets. The advantage it presents is that it allows us
to make an empty set:
Output
empty_set = set()
print(empty_set)
set()
random_set = set({"iHub", 1408, 3.142, (True, False)})
{1408, (True, False), 3.142, 'iHub'}
print(random_set)
Subi Subi
Subi Subi
Adding Elements
To add a single item, we can use the add() method. To add multiple items, we’d
have to use update(). The input for update() must be another set, list, tuple, or
string. Let’s add elements to an empty set:
Deleting Elements
empty_set = set()
print(empty_set) The discard() or remove() operations can be used to delete a
empty_set.add(1) particular item from a set:
odd_list = [1, 3, 5, 7]
Output
unordered_set = {9, 10, 11, 12, 13, 14, 15, 16, 17}
{9, 10, 11, 12, 13, 14, 15, 16, 17}
print(unordered_set)
[1, 3, 5, 7, 9, 11, 13, 15, 17]
for num in unordered_set:
if(not num % 2 == 0):
odd_list.append(num)
print(odd_list)
Subi Subi
Subi Subi
Set Theory Operations
Folks familiar with mathematics will know that sets have three main operations,
union, intersection, and difference.
The set data structure in Python supports all three.
Union
A union of two sets is the collection of all unique elements from both sets.
Since sets are unordered, the order of contents in the three outputs above
does not matter.
Subi Subi
Subi Subi
Intersection
The intersection of two sets is the collection of unique elements
which are common between them.
set_A = {1, 2, 3, 4}
set_B = {2, 8, 4, 16}
Output
Subi Subi
Subi Subi
Difference
The difference between two sets is the collection of all unique elements present
in the first set but not in the second.
In Python, the difference between two sets can be found using either the -
operator or the difference() method.
Do keep in mind that the difference operation is not associative, i.e., the
positions of the sets matter.
set_A - set_B returns the elements which are only present in set_A.
set_A = {1, 2, 3, 4}
set_B = {2, 8, 4, 16} Output
print(set_A - set_B)
print(set_A.difference(set_B)) {1, 3} {1, 3} {16, 8} {16, 8}
print(set_B - set_A)
print(set_B.difference(set_A))
Subi Subi
Subi Subi
Data Structure Conversions
The principle of conversion between built-in data
structures in Python is similar to that of Python’s
primitive data types.
Explicit Conversion
destination_structure_name(source_structure_object)
Output
star_wars_tup = ("Anakin", "Darth Vader", 1000)
print(star_wars_tup)
('Anakin', 'Darth Vader', 1000)
star_wars_set = {"Anakin", "Darth Vader", 1000} {1000, 'Anakin', 'Darth Vader'}
print(star_wars_set) {1: 'Anakin', 2: 'Darth Vader', 3:
star_wars_dict = {1: "Anakin", 2: "Darth Vader", 3: 1000} 1000}
print(star_wars_dict) ['Anakin', 'Darth Vader', 1000]
star_wars_list = list(star_wars_tup) # Converting from tuple [1000, 'Anakin', 'Darth Vader']
print(star_wars_list) [1, 2, 3]
star_wars_list = list(star_wars_set) # Converting from set
print(star_wars_list)
star_wars_list = list(star_wars_dict) # Converting from dictionary
print(star_wars_list)
Subi Subi
Subi Subi
star_wars_list = list(star_wars_dict.items())
print(star_wars_list)
Output
{1: 'Anakin', 2: 'Darth Vader', 3: 1000}
[(1, 'Anakin'), (2, 'Darth Vader'), (3, 1000)]
Subi Subi
Subi Subi
Converting to a Tuple
Any data structure can be converted to a tuple using the tuple() constructor. In
the case of a dictionary, only the keys will be converted to a tuple:
Output
star_wars_list = ["Anakin", "Darth Vader", 1000] ['Anakin', 'Darth Vader', 1000]
print(star_wars_list) {1000, 'Anakin', 'Darth Vader'}
star_wars_set = {"Anakin", "Darth Vader", 1000}
{1: 'Anakin', 2: 'Darth Vader', 3:
print(star_wars_set)
1000}
star_wars_dict = {1: "Anakin", 2: "Darth Vader", 3: 1000}
print(star_wars_dict) ('Anakin', 'Darth Vader', 1000)
star_wars_tup = tuple(star_wars_list) # Converting from list (1000, 'Anakin', 'Darth Vader')
print(star_wars_tup)
(1, 2, 3)
star_wars_tup = tuple(star_wars_set) # Converting from set
print(star_wars_tup)
star_wars_tup = tuple(star_wars_dict) # Converting from dictionary
print(star_wars_tup)
Subi Subi
Subi Subi
Converting to a Set
The set() constructor can be used to create a set out of any other data
structure. In the case of a dictionary, only the keys will be converted to a set:
Subi Subi
Subi Subi
Converting to a Dictionary
The dict() constructor cannot be used in the same way as the others because it requires
key-value pairs instead of just values. Hence, the data must be stored in a format where
pairs exist. For example, a list of tuples where the length of each tuple is 2 can be converted
into a dictionary. Those pairs will then be converted into key-value pairs:
Sample Input
my_list = [34, 82.6, "Darth Vader", 17, "Hannibal"]
Sample Output
my_tuple = (34, "Hannibal", 5)
There are several ways of solving the problem. Flesh out the loiHub
before moving on to the implementation.
my_list has already been created. You only need to make my_tuple.
Subi Subi
Subi Subi
Solution Review: From List to Tuple
my_list = [34, 82.6, "Darth Vader", 17, "Hannibal"]
my_tuple = (my_list[0], my_list[len(my_list) - 1], len(my_list))
print(my_tuple)
All we have to do is create a tuple with three elements. The first element of the tuple is the
first element of the list, which can be found using my_list[0].
The second element of the tuple is the last element in the list. my_list[len(my_list) - 1] or
simply my_list[-1] will give us this element. We could also have used the pop() method, but
that would alter the list.
We already know how to calculate the length of a data structure, so finding out the third
element of the tuple is pretty easy.
Subi Subi
Subi Subi
Exercise: Kth Maximum Integer in a List
Given a list of integers and a number k, find the kth largest integer in the list. The integer
will be stored in the kth_max variable.
For example, with a list of 7 integers, if k = 2, then kth_max will be equal to the
second-largest integer in the list. If k = 6, kth_max will equal the 6th largest integer.
Take some time to figure out the smartest way to solve this
problem. All the list methods and other data structures are
available for use. The list being used is called test_list.
Subi Subi
Subi Subi
Solution Review: Kth Maximum Integer in a List
The crux of this solution is the sort() method. Once the list is sorted, all we need
to do is identify the correct index. This can be done through [-k] which is
equivalent to [len(test_list)-k].
Subi Subi
Subi Subi
Exercise: Highs and Lows
You must implement the count_low_high() function. Its parameter is a list
of numbers.
At the end of the function, you must return a list that contains the
number of lows and highs, in that order.
Subi Subi
Subi Subi
Solution Review: Highs and Lows
Solution 1 - Using filter and lambda
def count_low_high(num_list):
if (len(num_list)==0):
return None
high_list = list(filter(lambda n: n > 50 or n % 3 == 0, num_list))
low_list = list(filter(lambda n: n <= 50 and not n % 3 == 0, num_list))
return [len(low_list), len(high_list)]
In this solution, the star of the show is the filter() function. We use it to filter all the elements that count
as a high in one list and all the rest in another list.
To count all the elements of both lists, we can simply use the len function.
We didn’t have to use lambdas but they definitely make the code simpler, and that’s what Python is all
about!
Subi Subi
Subi Subi
Solution 2 - List Comprehension
def count_low_high(num_list):
if (len(num_list)==0):
return None
high_list = len([n for n in num_list if n > 50 or n % 3 == 0])
low_list = len([n for n in num_list if n <= 50 and not n % 3 == 0])
return [low_list, high_list]
num_list = [20, 9, 51, 81, 50, 42, 77]
print(count_low_high(num_list))
Instead of using filter and lambda, another neat approach is to use list comprehension to
create our desired lists.
Following the list comprehension syntax, specify the element to be inserted into the new
list, a for loop which iterates the current list, and a condition that needs to be fulfilled.
Going one step further, we can calculate the length of the new list in the same line
Subi Subi
Subi Subi
Libraries
Subi Subi
Subi Subi
What is the Python Standard Library?
The Python Standard Library, PSL, is a collection of pre-defined modules, or
sets of methods which help us perform certain tasks in Python.
The library contains many useful utilities which spare us a lot of time. There are
different sorts of complex mathematical functions, high-level data types,
network programming tools, and this is just the tip of the iceberg!
Let’s import the datetime module which contains several methods related to the current
date and time. As always, these methods can be accessed using the . operator:
In the code above, datetime.date and datetime.datetime are classes in the datetime
module. Each class contains its own methods.
Subi Subi
Subi Subi
If we only want a particular class from a module, we can use the from keyword in
the following format:
We can also give our own names to the
from module import class modules that we import by using the as
keyword. Let’s rename datetime to dt and use
from datetime import date it in the program
# Now we only have the methods of the date class import datetime as dt
date_today = date.today() # Current date
print(date_today) date_today = dt.date.today() # Current date
# These won't work print(date_today)
# time_today = datetime.datetime.now()
# print (time_today.strftime("%H:%M:%S"))# Current time
time_today = dt.datetime.now()
print(time_today.strftime("%H:%M:%S")) #
Current time
Subi Subi
Subi Subi
Popular Modules: math
The math module offers a wide range of mathematical functions such as
factorial, trigonometric operations, etc.
import math
To get all math methods for complex numbers, use the cmath module instead.
Subi Subi
Subi Subi
heapq
The heapq module allows us to create the heap data structure. A heap is a
binary tree which always stores a special value at the top (root). A minheap
stores the smallest value at the top and a maxheap stores the largest value at
the top. The pop method returns the value at the top of the heap. Python’s
heapq creates a minheap by default.
import heapq
heap = [] # Empty heap
# Inserting elements in the heap
heapq.heappush(heap, 10)
heapq.heappush(heap, 70)
heapq.heappush(heap, 5)
heapq.heappush(heap, 35)
heapq.heappush(heap, 50)
# Popping the smallest value
minimum = heapq.heappop(heap)
print(minimum)
Subi Subi
Subi Subi
random
The random module is used for generating random numbers in Python. There
are several methods which allow us to generate different types of random
numbers. The random() method generates a random floating-point number
between 0 and 1, whereas uniform() returns a floating-point number within a
custom range.
import random
rand_num = random.random()
print(rand_num)
rand_num_in_range = random.uniform(30, 50) # A random
number between 30 and 50
print(rand_num_in_range)
str_list = ['a', 'b', 'c', 'd', 'e']
random.shuffle(str_list) # Randomly shuffle a list
print(str_list)
Subi Subi
Subi Subi
PyPI
What are Packages?
Python has a standard library that contains many different modules which
serve different purposes. However, we are not limited to these modules.
Developers from all over the world have contributed to increasing the
functionality of Python through packages.
Subi Subi
Subi Subi
Popular Packages
Subi Subi
Subi Subi
End of Bootcamp!!!!!
Subi Subi