0% found this document useful (0 votes)
23 views

Python Programming Notes

The document discusses Python data types including numbers, booleans, strings, lists, tuples, dictionaries and more. It covers built-in data types as well as mutable and immutable sequences. Examples of using each data type are provided.

Uploaded by

Mpumelelo Namelo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

Python Programming Notes

The document discusses Python data types including numbers, booleans, strings, lists, tuples, dictionaries and more. It covers built-in data types as well as mutable and immutable sequences. Examples of using each data type are provided.

Uploaded by

Mpumelelo Namelo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Contents

1 Romano F. Learn Python Programming. An in-depth in-


troduction 3ed 2021 2

2 Introduction 2

3 Data Types 3
3.1 Built-In Data types: Numbers and Booleans . . . . . . . . . . 3
3.1.1 Integers . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.1.2 Booleans . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.3 Floats . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.4 Complex numbers . . . . . . . . . . . . . . . . . . . . 5
3.1.5 Fractions and decimals . . . . . . . . . . . . . . . . . . 6
3.2 Built-In Data types: Immutable Sequences . . . . . . . . . . . 6
3.2.1 Strings and Bytes . . . . . . . . . . . . . . . . . . . . 6
3.2.2 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3 Built-In Data types: Mutable Sequences . . . . . . . . . . . . 9
3.3.1 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.3.2 Bytearrays . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4 Set Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.5 Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.6 Mapping Types: dictionaries . . . . . . . . . . . . . . . . . . 15
3.7 Other Data types . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.7.1 Dates and Times . . . . . . . . . . . . . . . . . . . . . 18
3.8 Collections module . . . . . . . . . . . . . . . . . . . . . . . . 20

4 Control Structures 24
4.1 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2 for Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.3 Iterators and iterables . . . . . . . . . . . . . . . . . . . . . . 25
4.4 while loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.5 break and continue . . . . . . . . . . . . . . . . . . . . . . . 28
4.6 The walrus operator := a special assignment statement . . . . 30
4.7 A few examples . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.8 The itertools module . . . . . . . . . . . . . . . . . . . . . 32

1
1 Romano F. Learn Python Programming. An in-
depth introduction 3ed 2021

2 Introduction
1. Structure
example���
c o r e . py���
run . py���
u t i l ���
__init__ . py���
db . py���
math . py���
network . py

• core and run are modules, util is a package


• == is special file to mark this folder as a package. it is empty.

2. Core Concepts

• Everything in python is an object.


• every object has identity, type and a value.
– identity is a name.
• namespace is a mapping from names to objects. namespaces are
places where names are associated

with objects.

• scope A scope is a textual region of a Python program, where a


namespace is directly

accessible. Directly accessible means that, when looking for an unqual-


ified reference to a name, Python tries to find it in the namespace.

• Scopes are determined statically, but actually, during runtime,


they are used

dynamically. This means that by inspecting the source code, you can
tell what the scope of an object is. There are four different scopes that
Python makes accessible (not necessarily all of them are present at the

2
same time, of course): •The local scope, which is the innermost one
and contains the local names. •The enclosing scope; that is, the
scope of any enclosing function. It contains non-local names and also
non-global names. •The global scope contains the global names.
•The built-in scope contains the built-in names. Python comes with
a set of functions that you can use in an off-the-shelf fashion, such as
print, all, abs, and so on. They live in the built-in scope.

3. Objects and classes


# b i k e . py
# l e t ’ s d e f i n e t h e c l a s s Bike
c l a s s Bike :
def __init__ ( s e l f , c o l o u r , f r a m e _ m a t e r i a l ) : #c o n s t r u c t o r
s e l f . colour = colour
s e l f . frame_material = frame_material
def brake ( s e l f ) :
print ( ” Braking ! ” )

# l e t ’ s create a couple of instances


red_bike = Bike ( ’ Red ’ , ’ Carbon ␣ f i b e r ’ )
bl u e _ b i k e = Bike ( ’ Blue ’ , ’ S t e e l ’ )

# l e t ’ s i n s p e c t t h e o b j e c t s we have , i n s t a n c e s o f t h e Bike c l a s s .
print ( red_bike . c o l o u r ) # p r i n t s : Red
print ( red_bike . f r a m e _ m a t e r i a l ) # p r i n t s : Carbon f i b e r
print ( b l u e _ b i k e . c o l o u r ) # p r i n t s : Blue
print ( b l u e _ b i k e . f r a m e _ m a t e r i a l ) # p r i n t s : S t e e l

# l e t ’ s brake !
red_bike . brake ( ) # p r i n t s : Braking !

• Objects are mutable

3 Data Types
3.1 Built-In Data types: Numbers and Booleans
• When an object is created it gets an id, type is set, and value is set.

3
• name = some_value, think of a name placed in the namespace that is
tied to the scope in which the

instruction was written, with an arrow pointing to an object that has an id,
a type, and a value.

• id(var) returns the id or reference.

• Mutable vs Immutable Types:

– int is immutable

• Python Data Types

3.1.1 Integers
int integer float floating point number bool boolean value: True or False
complex complex number, real and imaginary components str string, se-
quence of letters, numbers and symbols list list, formed with [ ] dict dic-
tionary, formed with {’key’=value} tuple an immutable list, formed with (
)

• Python type functions type() output a variable or object data type


len() return the length of a string, list dictionary or tuple str() convert
a float or int into a str (string) int() convert a float or str into an
int (integer) float() convert an int or str into an float (floating point
number)

– int() also returns numbers from string representations in a given


base: e.g. int('10110', base=2)

– Python List Operators [ ] indexing lst[1] 4 : start lst[:2] [ 2, 4 ] :


end lst[2:] [ 6, 8 ] : through lst[0:3] [ 2, 4, 6 ] : start, step, end+1
lst[0:5:2] [2, 6]

• Python Operators

– +a; a + b; -a; a - b; a * b; a / b; a % b; a // b; a **
b
– // - returns floored quotient of the operands
– / returns a float

4
3.1.2 Booleans
• bool is the class/type

• True and False are the two values.

• Operators: and, or, not

• Upcasting is a type conversion operation that goes from a subclass

to its parent. For example, True and False, which belong to a class derived
from the integer class, are converted back to integers when needed (1 and
0) respectively. Thus 1 + True is 2.

3.1.3 Floats
• stored as double precision 64 bit

• sys.float_info method in the sys package returns info about floating


point numbers on a particular system

3.1.4 Complex numbers


• c = 3.14 + 2.73j or c = complex(3.14,2.73)

• Examples and functions

>>> c = 3 . 1 4 + 2 . 7 3 j
>>> c = complex ( 3 . 1 4 , 2 . 7 3 ) # same as a b ov e
>>> c . r e a l # r e a l p a r t
3.14
>>> c . imag # i m a g i n a r y p a r t
2.73
>>> c . c o n j u g a t e ( ) # c o n j u g a t e o f A + Bj i s A − Bj
(3.14 −2.73 j )
>>> c ∗ 2 # m u l t i p l i c a t i o n i s a l l o w e d
(6.28+5.46 j )
>>> c ∗∗ 2 # power o p e r a t i o n as w e l l
(2.4067000000000007+17.1444 j )
>>> d = 1 + 1 j # a d d i t i o n and s u b t r a c t i o n as w e l l
>>> c − d
(2.14+1.73 j )

5
3.1.5 Fractions and decimals
• Fractions

>>> from f r a c t i o n s import F r a c t i o n


>>> F r a c t i o n ( 1 0 , 6 ) # mad h a t t e r ?
F r a c t i o n ( 5 , 3 ) # n o t i c e i t ’ s been s i m p l i f i e d
>>> F r a c t i o n ( 1 , 3 ) + F r a c t i o n ( 2 , 3 ) # 1/3 + 2/3 == 3/3 == 1/1
Fraction (1 , 1)
>>> f = F r a c t i o n ( 1 0 , 6 )
>>> f . numerator
5
>>> f . denominator
3
>>> f . a s _ i n t e g e r _ r a t i o ( ) #t h i s method a l s o works f o r i n t e g e r s and Booleans
(5 , 3)

• Decimals
>>> from d e c i m a l import Decimal a s D # rename f o r b r e v i t y
>>> D( 3 . 1 4 ) # pi , from f l o a t , so a p p r o x i m a t i o n i s s u e s
Decimal ( ’ 3 . 1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 4 3 4 4 9 7 8 7 5 8 0 1 7 5 3 2 5 2 7 4 4 6 7 4 6 8 2 6 1 7 1 8 7 5 ’ )
>>> D( ’ 3 . 1 4 ’ ) # pi , from a s t r i n g , so no a p p r o x i m a t i o n i s s u e s
Decimal ( ’ 3 . 1 4 ’ )
>>> D( 0 . 1 ) ∗ D( 3 ) − D( 0 . 3 ) # from f l o a t , we s t i l l have t h e i s s u e
Decimal ( ’ 2 . 7 7 5 5 5 7 5 6 1 5 6 5 1 5 6 5 4 0 4 2 3 6 3 1 6 6 8E−17 ’ )
>>> D( ’ 0 . 1 ’ ) ∗ D( 3 ) − D( ’ 0 . 3 ’ ) # from s t r i n g , a l l p e r f e c t
Decimal ( ’ 0 . 0 ’ )
>>> D( ’ 1 . 4 ’ ) . a s _ i n t e g e r _ r a t i o ( ) # 7/5 = 1 . 4 ( i s n ’ t t h i s c o o l ? ! )
(7 , 5)

3.2 Built-In Data types: Immutable Sequences


3.2.1 Strings and Bytes
• Creating Strings

>>> # 4 ways t o make a s t r i n g


>>> s t r 1 = ’ This ␣ i s ␣ a ␣ s t r i n g . ␣We␣ b u i l t ␣ i t ␣ with ␣ s i n g l e ␣ q u o t e s . ’
>>> s t r 2 = ” This ␣ i s ␣ a l s o ␣ a ␣ s t r i n g , ␣ but ␣ b u i l t ␣ with ␣ d o u b l e ␣ q u o t e s . ”

6
>>> s t r 3 = ’ ’ ’ This i s b u i l t u s i n g t r i p l e q u o t e s ,
. . . so i t can span m u l t i p l e l i n e s . ’ ’ ’
>>> s t r 4 = ””” This t o o
. . . i s a m u l t i l i n e one
. . . b u i l t w i t h t r i p l e d o u b l e −q u o t e s . ”””
>>> s t r 4 #A
’ This ␣ t o o \ n i s ␣ a ␣ m u l t i l i n e ␣ one \ n b u i l t ␣ with ␣ t r i p l e ␣ double−q u o t e s . ’
>>> print ( s t r 4 ) #B
This t o o
i s a m u l t i l i n e one
b u i l t with t r i p l e double−q u o t e s .

• String Functions
>>> len ( s t r 1 )
49
>>> s = ’ H e l l o ␣ There ’
>>> s . r e m o v e p r e f i x ( ’ H e l l ’ )
’ o␣ There ’
>>> s . r e m o v e s u f f i x ( ’ h e r e ’ )
’ H e l l o ␣T ’
>>> s . r e m o v e p r e f i x ( ’ Ooops ’ )
’ H e l l o ␣ There ’
>>> s = ” This ␣ i s ␣ŋ ü í c 0 d e ” # u n i c o d e s t r i n g : code p o i n t s
>>> type ( s )
<c l a s s ’ s t r ’>
>>> encoded_s = s . encode ( ’ u t f −8 ’ ) # u t f −8 encoded v e r s i o n o f s
>>> encoded_s
b ’ This ␣ i s ␣ \ xc3 \ xbc \ xc5 \ x8b \ xc3 \ xadc0de ’ # r e s u l t : b y t e s o b j e c t
>>> type ( encoded_s ) # a n o t h e r way t o v e r i f y i t
<c l a s s ’ b y t e s ’>
>>> encoded_s . decode ( ’ u t f −8 ’ ) # l e t ’ s r e v e r t t o t h e o r i g i n a l
’ This ␣ i s ␣ŋ ü í c 0 d e ’
>>> bytes_obj = b”A␣ b y t e s ␣ o b j e c t ”
>>> type ( bytes_obj

• Indexing and Slicing Strings


#my_sequence [ s t a r t : s t o p : s t e p ] − d e f a u l t s : s t a r t o f s t r i n g , end o f s t r i n
>>> s = ”The␣ t r o u b l e ␣ i s ␣ you ␣ t h i n k ␣ you ␣ have ␣ time . ”
>>> s [ 0 ] # i n d e x i n g a t p o s i t i o n 0 , which i s t h e f i r s t cha r

7
’T ’
>>> s [ 5 ] # i n d e x i n g a t p o s i t i o n 5 , which i s t h e s i x t h cha r
’r ’
>>> s [ : 4 ] # s l i c i n g , we s p e c i f y o n l y t h e s t o p p o s i t i o n
’ The␣ ’
>>> s [ 4 : ] # s l i c i n g , we s p e c i f y o n l y t h e s t a r t p o s i t i o n
’ t r o u b l e ␣ i s ␣ you ␣ t h i n k ␣ you ␣ have ␣ time . ’
>>> s [ 2 : 1 4 ] # s l i c i n g , b o t h s t a r t and s t o p p o s i t i o n s
’ e␣ trouble ␣ i s ’
>>> s [ 2 : 1 4 : 3 ] # s l i c i n g , s t a r t , s t o p and s t e p ( e v e r y 3 c h a r s )
’ erb ␣ ’
>>> s [ : ] # q u i c k way o f making a copy
’ The␣ t r o u b l e ␣ i s ␣ you ␣ t h i n k ␣ you ␣ have ␣ time . ’
>>> s [ : : − 1 ] #r e v e r s e s a s t r i n g

• String Formatting
>>> g r e e t _ p o s i t i o n a l = ’ H e l l o ␣ { } ! ’
>>> g r e e t _ p o s i t i o n a l . format ( ’ F a b r i z i o ’ )
’ Hello ␣ Fabrizio ! ’
>>> g r e e t _ p o s i t i o n a l = ’ H e l l o ␣ {} ␣ { } ! ’
>>> g r e e t _ p o s i t i o n a l . format ( ’ F a b r i z i o ’ , ’ Romano ’ )
’ H e l l o ␣ F a b r i z i o ␣Romano ! ’
>>> g r e e t _ p o s i t i o n a l _ i d x = ’ This ␣ i s ␣ { 0 } ! ␣ {1} ␣ l o v e s ␣ { 0 } ! ’
>>> g r e e t _ p o s i t i o n a l _ i d x . format ( ’ Python ’ , ’ H e i n r i c h ’ )
’ This ␣ i s ␣ Python ! ␣ H e i n r i c h ␣ l o v e s ␣ Python ! ’
>>> g r e e t _ p o s i t i o n a l _ i d x . format ( ’ C o f f e e ’ , ’ Fab ’ )
’ This ␣ i s ␣ C o f f e e ! ␣Fab␣ l o v e s ␣ C o f f e e ! ’
>>> keyword = ’ H e l l o , ␣my␣name␣ i s ␣ {name} ␣ { last_name } ’
>>> keyword . format ( name= ’ F a b r i z i o ’ , last_name= ’ Romano ’ )
’ H e l l o , ␣my␣name␣ i s ␣ F a b r i z i o ␣Romano ’

– and from python 3.8


>>> name = ’ Fab ’
>>> age = 42
>>> f ” H e l l o ! ␣My␣name␣ i s ␣ {name} ␣and␣ I ’m␣{ age } ”
” H e l l o ! ␣My␣name␣ i s ␣Fab␣and␣ I ’m␣ 42 ”
>>> from math import p i
>>> f ”No␣ a r g u i n g ␣ with ␣ { p i } , ␣ i t ’ s ␣ i r r a t i o n a l . . . ”
”No␣ a r g u i n g ␣ with ␣ 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 , ␣ i t ’ s ␣ i r r a t i o n a l . . . ”

8
>>> u s e r = ’ h e i n r i c h ’
>>> password = ’ super−s e c r e t ’
>>> f ” Log␣ i n ␣ with : ␣ { u s e r } ␣and␣ { password } ”
’ Log␣ i n ␣ with : ␣ h e i n r i c h ␣and␣ super−s e c r e t ’
>>> f ” Log␣ i n ␣ with : ␣ { u s e r=}␣and␣ { password=}”
” Log␣ i n ␣ with : ␣ u s e r =’ h e i n r i c h ’ ␣and␣ password =’ super−s e c r e t ’ ”

3.2.2 Tuples
• A tuple is a sequence of arbitrary Python objects separated by com-
mas.
>>> t = ( ) # empty t u p l e
>>> type ( t )
<c l a s s ’ t u p l e ’>
>>> one_element_tuple = ( 4 2 , ) # you need t h e comma !
>>> t h r e e _ e l e m e n t s _ t u p l e = ( 1 , 3 , 5 ) # b r a c e s a r e o p t i o n a l h e r e
>>> a , b , c = 1 , 2 , 3 # t u p l e f o r m u l t i p l e a s s i g n m e n t
>>> a , b , c # i m p l i c i t t u p l e t o p r i n t w i t h one i n s t r u c t i o n
(1 , 2 , 3)
>>> 3 in t h r e e _ e l e m e n t s _ t u p l e # membership t e s t
True

>>> a, b = 0, 1
>>> a , b = b , a # swap
>>> a, b
(1 , 0)

3.3 Built-In Data types: Mutable Sequences


3.3.1 Lists
• Creating Lists
>>> [ ] # empty l i s t
[]
>>> l i s t ( ) # same as [ ]
[]
>>> [ 1 , 2 , 3 ] # as w i t h t u p l e s , i t e m s a r e comma s e p a r a t e d
[1 , 2 , 3]
>>> [ x + 5 fo r x in [ 2 , 3 , 4 ] ] # L i s t Comprehension

9
[7 , 8 , 9]
>>> l i s t ( ( 1 , 3 , 5 , 7 , 9 ) ) # l i s t from a t u p l e
[1 , 3 , 5 , 7 , 9]
>>> l i s t ( ’ h e l l o ’ ) # l i s t from a s t r i n g
[ ’h ’ , ’ e ’ , ’ l ’ , ’ l ’ , ’o ’ ]

– List methods
>>> a = [ 1 , 2 , 1 , 3 ]
>>> a . append ( 1 3 ) # we can append a n y t h i n g a t t h e end
>>> a
[1 , 2 , 1 , 3 , 13]
>>> a . count ( 1 ) # how many ‘1 s ‘ a r e t h e r e i n t h e l i s t ?
2
>>> a . extend ( [ 5 , 7 ] ) # e x t e n d t h e l i s t by a n o t h e r ( or s e q u e n c e )
>>> a
[ 1 , 2 , 1 , 3 , 13 , 5 , 7 ]
>>> a . i n d e x ( 1 3 ) # p o s i t i o n o f ‘ 1 3 ‘ i n t h e l i s t (0− b a s e d i n d e x i n g )
4
>>> a . i n s e r t ( 0 , 1 7 ) # i n s e r t ‘ 1 7 ‘ a t p o s i t i o n 0
>>> a
[ 1 7 , 1 , 2 , 1 , 3 , 13 , 5 , 7 ]
>>> a . pop ( ) # pop ( remove and r e t u r n ) l a s t e l e m e n t
7
>>> a . pop ( 3 ) # pop e l e m e n t a t p o s i t i o n 3
1
>>> a
[ 1 7 , 1 , 2 , 3 , 13 , 5 ]
>>> a . remove ( 1 7 ) # remove ‘ 1 7 ‘ from t h e l i s t
>>> a
[ 1 , 2 , 3 , 13 , 5 ]
>>> a . r e v e r s e ( ) # r e v e r s e t h e o r d e r o f t h e e l e m e n t s i n t h e l i s t
>>> a
[ 5 , 13 , 3 , 2 , 1 ]
>>> a . s o r t ( ) # s o r t t h e l i s t
>>> a
[1 , 2 , 3 , 5 , 13]
>>> a . c l e a r ( ) # remove a l l e l e m e n t s from t h e l i s t
>>> a
[]

10
>>> a = l i s t ( ’ h e l l o ’ ) # makes a l i s t from a s t r i n g
>>> a
[ ’h ’ , ’ e ’ , ’ l ’ , ’ l ’ , ’o ’ ]
>>> a . append ( 1 0 0 ) # append 100 , h e t e r o g e n e o u s t y p e
>>> a
[ ’h ’ , ’ e ’ , ’ l ’ , ’ l ’ , ’o ’ , 100]
>>> a . extend ( ( 1 , 2 , 3 ) ) # e x t e n d u s i n g t u p l e
>>> a
[ ’h ’ , ’ e ’ , ’ l ’ , ’ l ’ , ’ o ’ , 100 , 1 , 2 , 3 ]
>>> a . extend ( ’ . . . ’ ) # e x t e n d u s i n g s t r i n g
>>> a
[ ’h ’ , ’ e ’ , ’ l ’ , ’ l ’ , ’ o ’ , 100 , 1 , 2 , 3 , ’ . ’ , ’ . ’ , ’ . ’ ]

• List operations
>>> a = [1 , 3 , 5 , 7]
>>> min( a ) # minimum v a l u e i n t h e l i s t
1
>>> max( a ) # maximum v a l u e i n t h e l i s t
7
>>> sum( a ) # sum o f a l l v a l u e s i n t h e l i s t
16
>>> from math import prod
>>> prod ( a ) # p r o d u c t o f a l l v a l u e s i n t h e l i s t
105
>>> len ( a ) # number o f e l e m e n t s i n t h e l i s t
4
>>> b = [6 , 7 , 8]
>>> a + b # ‘+ ‘ w i t h l i s t means c o n c a t e n a t i o n
[1 , 3 , 5 , 7 , 6 , 7 , 8]
>>> a ∗ 2 # ‘ ∗ ‘ has a l s o a s p e c i a l meaning
[1 , 3 , 5 , 7 , 1 , 3 , 5 , 7]

• Sorting
>>> from o p e r a t o r import i t e m g e t t e r
>>> a = [ ( 5 , 3 ) , ( 1 , 3 ) , ( 1 , 2 ) , ( 2 , −1) , ( 4 , 9 ) ]
>>> sorted ( a )
[ ( 1 , 2 ) , ( 1 , 3 ) , ( 2 , −1) , ( 4 , 9 ) , ( 5 , 3 ) ]
>>> sorted ( a , key=i t e m g e t t e r ( 0 ) )
[ ( 1 , 3 ) , ( 1 , 2 ) , ( 2 , −1) , ( 4 , 9 ) , ( 5 , 3 ) ]

11
>>> sorted ( a , key=i t e m g e t t e r ( 0 , 1 ) )
[ ( 1 , 2 ) , ( 1 , 3 ) , ( 2 , −1) , ( 4 , 9 ) , ( 5 , 3 ) ]
>>> sorted ( a , key=i t e m g e t t e r ( 1 ) )
[ ( 2 , −1) , ( 1 , 2 ) , ( 5 , 3 ) , ( 1 , 3 ) , ( 4 , 9 ) ]
>>> sorted ( a , key=i t e m g e t t e r ( 1 ) , r e v e r s e=True )
[ ( 4 , 9 ) , ( 5 , 3 ) , ( 1 , 3 ) , ( 1 , 2 ) , ( 2 , −1)]

– Explanation

a is a list of tuples. This means each element in a is a tuple (a 2-tuple


in this case). When we call sorted(my_ list), we get a sorted version of
my_list. In this case, the sorting on a 2-tuple works by sorting them
on the first item in the tuple, and on the second when the first one is
the same. You can see this behavior in the result of sorted(a), which
yields [(1, 2), (1, 3), …]. Python also gives us the ability to control
which element(s) of the tuple the sorting must be run against. Notice
that when we instruct the sorted function, to work on the first element
of each tuple (with key=itemgetter(0)), the result is different: [(1, 3),
(1, 2), …]. The sorting is done only on the first element of each tuple
(which is the one at position 0). If we want to replicate the default
behavior of a simple sorted(a) call, we need to use key=itemgetter(0,
1), which tells Python to sort first on the elements at position 0 within
the tuples, and then on those at position 1.

3.3.2 Bytearrays
• Items in a bytearray are integers in the range [0, 256)

• Creating bytearrays

>>> bytearray ( ) # empty b y t e a r r a y o b j e c t


bytearray ( b ’ ’ )
>>> bytearray ( 1 0 ) # z ero − f i l l e d i n s t a n c e w i t h g i v e n l e n g t h
bytearray ( b ’ \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 ’ )
>>> bytearray ( range ( 5 ) ) # b y t e a r r a y from i t e r a b l e o f i n t e g e r s
bytearray ( b ’ \ x00 \ x01 \ x02 \ x03 \ x04 ’ )
>>> name = bytearray ( b ’ Lina ’ ) #A − b y t e a r r a y from b y t e s
>>> name . r e p l a c e ( b ’L ’ , b ’ l ’ )
bytearray ( b ’ l i n a ’ )
>>> name . en d s w i t h ( b ’ na ’ )

12
True
>>> name . upper ( )
bytearray ( b ’LINA ’ )
>>> name . count ( b ’L ’ )
1

• bytearrays considered as mutable strings.

3.4 Set Types


• set and frozenset. The set type is mutable, while frozenset is im-
mutable

• They are unordered collections of immutable objects.

• Hashability is a characteristic that allows an object to be used as a set


member as

well as a key for a dictionary

• Examples
>>> small_primes = set ( ) # empty s e t
>>> small_primes . add ( 2 ) # a d d i n g one e l e m e n t a t a time
>>> small_primes . add ( 3 )
>>> small_primes . add ( 5 )
>>> small_primes
{ 2 , 3 , 5}
>>> small_primes . add ( 1 ) # Look what I ’ ve done , 1 i s not a prime !
>>> small_primes
{ 1 , 2 , 3 , 5}
>>> small_primes . remove ( 1 ) # so l e t ’ s remove i t
>>> 3 in small_primes # membership t e s t
True
>>> 4 in small_primes
False
>>> 4 not in small_primes # n e g a t e d membership t e s t
True
>>> small_primes . add ( 3 ) # t r y i n g t o add 3 a g a i n
>>> small_primes
{ 2 , 3 , 5} # no change , d u p l i c a t i o n i s not a l l o w e d

13
>>> b i g g e r _ p r i m e s = set ( [ 5 , 7 , 1 1 , 1 3 ] ) # f a s t e r c r e a t i o n
>>> small_primes | b i g g e r _ p r i m e s # union o p e r a t o r ‘ | ‘
{2 , 3 , 5 , 7 , 1 1 , 13}
>>> small_primes & b i g g e r _ p r i m e s # i n t e r s e c t i o n o p e r a t o r ‘& ‘
{5}
>>> small_primes − b i g g e r _ p r i m e s # d i f f e r e n c e o p e r a t o r ‘ − ‘
{2 , 3}
>>> small_primes = { 2 , 3 , 5 , 5 , 3}
>>> small_primes
{2 , 3 , 5}

• Examples frozenset
>>> small_primes = frozenset ( [ 2 , 3 , 5 , 7 ] )
>>> b i g g e r _ p r i m e s = frozenset ( [ 5 , 7 , 1 1 ] )
>>> small_primes . add ( 1 1 ) # we cannot add t o a f r o z e n s e t
Traceback ( most r e c e n t c a l l l a s t ) :
F i l e ”<s t d i n >” , l i n e 1 , in <module>
A t t r i b u t e E r r o r : ’ f r o z e n s e t ’ object has no a t t r i b u t e ’ add ’
>>> small_primes . remove ( 2 ) # nor can we remove
Traceback ( most r e c e n t c a l l l a s t ) :
F i l e ”<s t d i n >” , l i n e 1 , in <module>
A t t r i b u t e E r r o r : ’ f r o z e n s e t ’ object has no a t t r i b u t e ’ remove ’
>>> small_primes & b i g g e r _ p r i m e s # i n t e r s e c t , union , e t c . a l l o w e d
frozenset ( { 5 , 7 } )

3.5 Indexing

>>> a = l i s t ( range ( 1 0 ) ) # ‘ a ‘ has 10 e l e m e n t s . L a s t one i s 9 .


>>> a
[0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9]
>>> len ( a ) # i t s l e n g t h i s 10 e l e m e n t s
10
>>> a [ len ( a ) − 1 ] # p o s i t i o n o f l a s t one i s l e n ( a ) − 1
9
>>> a [ −1] # b u t we don ’ t need l e n ( a ) ! Python r o c k s !
9
>>> a [ −2] # e q u i v a l e n t t o l e n ( a ) − 2
8
>>> a [ −3] # e q u i v a l e n t t o l e n ( a ) − 3

14
7

3.6 Mapping Types: dictionaries


• A dictionary maps keys to values. Keys need to be hashable objects,
while values can

be of any arbitrary type. Dictionaries are also mutable objects.

• Creating Dictionaries
>>> a = dict (A=1, Z=−1)
>>> b = { ’A ’ : 1 , ’ Z ’ : −1}
>>> c = dict ( zip ( [ ’A ’ , ’ Z ’ ] , [ 1 , −1]))
>>> d = dict ( [ ( ’A ’ , 1 ) , ( ’ Z ’ , −1)])
>>> e = dict ( { ’ Z ’ : −1, ’A ’ : 1 } )
>>> a == b == c == d == e # a r e t h e y a l l t h e same?
True # They a r e i n d e e d
>>> l i s t ( zip ( [ ’ h ’ , ’ e ’ , ’ l ’ , ’ l ’ , ’ o ’ ] , [ 1 , 2 , 3 , 4 , 5 ] ) )
[ ( ’h ’ , 1) , ( ’ e ’ , 2) , ( ’ l ’ , 3) , ( ’ l ’ , 4) , ( ’o ’ , 5)]
>>> l i s t ( zip ( ’ h e l l o ’ , range ( 1 , 6 ) ) ) # e q u i v a l e n t , more p y t h o n i c
[ ( ’h ’ , 1) , ( ’ e ’ , 2) , ( ’ l ’ , 3) , ( ’ l ’ , 4) , ( ’o ’ , 5)]

• wrap the list() constructor around the zip() call (the reason is zip()
returns

an iterator, not a list, so if we want to see the result, we need to exhaust


that iterator into something—a list in this case)

• Dictionary Methods
>>> d = {}
>>> d [ ’ a ’ ] = 1 # l e t ’ s s e t a c o u p l e o f ( key , v a l u e ) p a i r s
>>> d [ ’ b ’ ] = 2
>>> len ( d ) # how many p a i r s ?
2
>>> d [ ’ a ’ ] # what i s t h e v a l u e o f ’ a ’?
1
>>> d # how d o e s ‘ d ‘ l o o k now?
{ ’ a ’ : 1 , ’ b ’ : 2}
>>> del d [ ’ a ’ ] # l e t ’ s remove ‘ a ‘
>>> d

15
{ ’ b ’ : 2}
>>> d [ ’ c ’ ] = 3 # l e t ’ s add ’ c ’ : 3
>>> ’ c ’ in d # membership i s c h e c k e d a g a i n s t t h e k e y s
True
>>> 3 in d # not t h e v a l u e s
False
>>> ’ e ’ in d
False
>>> d . c l e a r ( ) # l e t ’ s c l e a n e v e r y t h i n g from t h i s d i c t i o n a r y
>>> d
{}

• Working with Dictionaries

– keys() returns all the keys in the dictionary, values() returns all
the values in the dictionary, and items() returns all the (key,
value) pairs in the dictionary.

>>> d = dict ( zip ( ’ h e l l o ’ , range ( 5 ) ) )


>>> d
{ ’ h ’ : 0 , ’ e ’ : 1 , ’ l ’ : 3 , ’ o ’ : 4}
>>> d . k e y s ( )
dict_keys ( [ ’h ’ , ’ e ’ , ’ l ’ , ’ o ’ ] )
>>> d . v a l u e s ( )
dict_values ([ 0 , 1 , 3 , 4])
>>> d . i t e m s ( )
dict_items ( [ ( ’h ’ , 0) , ( ’ e ’ , 1) , ( ’ l ’ , 3) , ( ’ o ’ , 4 ) ] )
>>> 3 in d . v a l u e s ( )
True
>>> ( ’ o ’ , 4 ) in d . i t e m s ( )
True

• Dictionary Methods
>>> d
{ ’ h ’ : 0 , ’ e ’ : 1 , ’ l ’ : 3 , ’ o ’ : 4}
>>> d . popitem ( ) # removes a random item ( u s e f u l i n a l g o r i t h m s )
( ’ o ’ , 4)
>>> d
{ ’ h ’ : 0 , ’ e ’ : 1 , ’ l ’ : 3}
>>> d . pop ( ’ l ’ ) # remove item w i t h key ‘ l ‘

16
3
>>> d . pop ( ’ not−a−key ’ ) # remove a key not i n d i c t i o n a r y : KeyError
Traceback ( most r e c e n t c a l l l a s t ) :
F i l e ”<s t d i n >” , l i n e 1 , in <module>
KeyError : ’ not−a−key ’
>>> d . pop ( ’ not−a−key ’ , ’ d e f a u l t −v a l u e ’ ) # w i t h a d e f a u l t v a l u e ?
’ d e f a u l t −v a l u e ’ # we g e t t h e d e f a u l t v a l u e
>>> d . update ( { ’ a n o t h e r ’ : ’ v a l u e ’ } ) # we can u p d a t e d i c t t h i s way
>>> d . update ( a=13) # or t h i s way ( l i k e a f u n c t i o n c a l l )
>>> d
{ ’ h ’ : 0 , ’ e ’ : 1 , ’ a n o t h e r ’ : ’ v a l u e ’ , ’ a ’ : 13}
>>> d . g e t ( ’ a ’ ) # same as d [ ’ a ’ ] b u t i f key i s m i s s i n g no KeyError
13
>>> d . g e t ( ’ a ’ , 1 7 7 ) # d e f a u l t v a l u e used i f key i s m i s s i n g
13
>>> d . g e t ( ’ b ’ , 1 7 7 ) # l i k e i n t h i s c a s e
177
>>> d . g e t ( ’ b ’ ) # key i s not t h e r e , so None i s r e t u r n e d
>>> d = {}
>>> d . s e t d e f a u l t ( ’ a ’ , 1 ) # ’ a ’ i s m i s s i n g , we g e t d e f a u l t v a l u e
1
>>> d
{ ’ a ’ : 1} # a l s o , t h e key / v a l u e p a i r ( ’ a ’ , 1) has now been added
>>> d . s e t d e f a u l t ( ’ a ’ , 5 ) # l e t ’ s t r y t o o v e r r i d e t h e v a l u e
1
>>> d
{ ’ a ’ : 1} # no o v e r r i d e , as e x p e c t e d

– None: None is frequently used to represent the absence of a value,


and

it is quite commonly used as a default value for arguments in function


declaration. Some inexperienced coders sometimes write code that
returns either False or None. Both False and None evaluate to False
in a Boolean context, so it may seem that there

is not much difference between them. But actually, we would argue the
contrary, that there is an important difference: False means that we have
information, and the information we have is False. None means no informa-
tion; no information is very different from information that is False.

17
• Union operator for dictionaries in python 3.9 +
>>> d = { ’ a ’ : ’A ’ , ’ b ’ : ’B ’ }
>>> e = { ’ b ’ : 8 , ’ c ’ : ’C ’ }
>>> d | e
{ ’ a ’ : ’A ’ , ’ b ’ : 8 , ’ c ’ : ’C ’ }
>>> e | d
{ ’ b ’ : ’B ’ , ’ c ’ : ’C ’ , ’ a ’ : ’A ’ }
>>> {∗∗d , ∗∗ e }
{ ’ a ’ : ’A ’ , ’ b ’ : 8 , ’ c ’ : ’C ’ }
>>> {∗∗ e , ∗∗d}
{ ’ b ’ : ’B ’ , ’ c ’ : ’C ’ , ’ a ’ : ’A ’ }
>>> d |= e
>>> d
{ ’ a ’ : ’A ’ , ’ b ’ : 8 , ’ c ’ : ’C ’ }

3.7 Other Data types


3.7.1 Dates and Times

>>> from d a t e t i m e import date , datetime , t i m e d e l t a , t i m e z o n e


>>> import time
>>> import c a l e n d a r a s c a l
>>> from z o n e i n f o import Z o n e I n f o
>>> from d a t e t i m e import date , datetime , t i m e d e l t a , t i m e z o n e
>>> import time
>>> import c a l e n d a r a s c a l
>>> from z o n e i n f o import Z o n e I n f o
’ 2021−03−28 ’
>>> today . weekday ( )
6
>>> c a l . day_name [ today . weekday ( ) ]
’ Sunday ’
>>> today . day , today . month , today . y e a r
(28 , 3 , 2021)
>>> today . t i m e t u p l e ( )
time . s t r u c t _ t i m e (
tm_year =2021 , tm_mon=3, tm_mday=28 ,

18
tm_hour=0, tm_min=0, tm_sec=0,
tm_wday=6, tm_yday=87 , tm_isdst=−1
)
>>> time . c t i m e ( )
’ Sun␣Mar␣ 28 ␣ 1 5 : 2 3 : 1 7 ␣ 2021 ’
>>> time . d a y l i g h t
1
>>> time . gmtime ( )
time . s t r u c t _ t i m e (
tm_year =2021 , tm_mon=3, tm_mday=28 ,
tm_hour=14 , tm_min=23 , tm_sec =34 ,
tm_wday=6, tm_yday=87 , tm_isdst=0
)
>>> time . gmtime ( 0 )
time . s t r u c t _ t i m e (
tm_year =1970 , tm_mon=1, tm_mday=1,
tm_hour=0, tm_min=0, tm_sec=0,
tm_wday=3, tm_yday=1, tm_isdst=0
)
>>> time . l o c a l t i m e ( )
time . s t r u c t _ t i m e (
tm_year =2021 , tm_mon=3, tm_mday=28 ,
tm_hour=15 , tm_min=23 , tm_sec =50 ,
tm_wday=6, tm_yday=87 , tm_isdst=1
)
>>> time . time ( )
1616941458.149149
>>> now = d a t e t i m e . now ( )
>>> utcnow = d a t e t i m e . utcnow ( )
>>> now
datetime . datetime (2021 , 3 , 28 , 15 , 25 , 16 , 258274)
>>> utcnow
datetime . datetime (2021 , 3 , 28 , 14 , 25 , 22 , 918195)
>>> now . d a t e ( )
datetime . date (2021 , 3 , 28)
>>> now . day , now . month , now . y e a r
(28 , 3 , 2021)
>>> now . d a t e ( ) == d a t e . today ( )
True
>>> now = d a t e t i m e . now ( )

19
>>> utcnow = d a t e t i m e . utcnow ( )
>>> now
datetime . datetime (2021 , 3 , 28 , 15 , 25 , 16 , 258274)
>>> utcnow
datetime . datetime (2021 , 3 , 28 , 14 , 25 , 22 , 918195)
>>> now . d a t e ( )
datetime . date (2021 , 3 , 28)
>>> now . day , now . month , now . y e a r
(28 , 3 , 2021)
>>> now . d a t e ( ) == d a t e . today ( )
True
>>> f_bday = d a t e t i m e (
1 9 7 5 , 1 2 , 2 9 , 1 2 , 5 0 , t z i n f o=Z o n e I n f o ( ’ Europe /Rome ’ )
)
>>> h_bday = d a t e t i m e (
1 9 8 1 , 1 0 , 7 , 1 5 , 3 0 , 5 0 , t z i n f o=t i m e z o n e ( t i m e d e l t a ( h o u r s =2))
)
>>> d i f f = h_bday − f_bday
>>> type ( d i f f )
<c l a s s ’ d a t e t i m e . t i m e d e l t a ’>
>>> d i f f . days
2109
>>> d i f f . t o t a l _ s e c o n d s ( )
182223650.0
>>> today + t i m e d e l t a ( days =49)
datetime . date (2021 , 5 , 16)
>>> now + t i m e d e l t a ( weeks =7)
datetime . datetime (2021 , 5 , 16 , 15 , 25 , 16 , 258274)
Two o b j e c t s have been c r e a t e d t h a t r e p r e s e n t F a b r i z i o and Hei

3.8 Collections module


• collections namedtuple() : Factory function for creating tuple sub-
classes with named fields deque : List-like container with fast appends
and pops on either end ChainMap : Dictionary-like class for creat-
ing a single view of multiple mappings Counter : Dictionary subclass
for counting hashable objects OrderedDict : Dictionary subclass with
methods that allow for re-ordering entries defaultdict : Dictionary sub-
class that calls a factory function to supply missing values UserDict
: Wrapper around dictionary objects for easier dictionary subclassing

20
UserList : Wrapper around list objects for easier list subclassing User-
String : Wrapper around string objects for easier string subclassing

• namedtuple

– A namedtuple is a tuple-like object that has fields accessible by


attribute lookup, as

well as being indexable and iterable (it’s a subclass of tuple)

– example
# Using t u p l e
>>> v i s i o n = ( 9 . 5 , 8 . 8 )
>>> v i s i o n
(9.5 , 8.8)
>>> v i s i o n [ 0 ] # l e f t eye ( i m p l i c i t p o s i t i o n a l r e f e r e n c e )
9.5
>>> v i s i o n [ 1 ] # r i g h t eye ( i m p l i c i t p o s i t i o n a l r e f e r e n c e )
8.8

# same code w i t h namedtuple


>>> from c o l l e c t i o n s import namedtuple
>>> V i s i o n = namedtuple ( ’ V i s i o n ’ , [ ’ l e f t ’ , ’ r i g h t ’ ] )
>>> v i s i o n = V i s i o n ( 9 . 5 , 8 . 8 )
>>> v i s i o n [ 0 ]
9.5
>>> v i s i o n . l e f t # same as v i s i o n [ 0 ] , b u t e x p l i c i t
9.5
>>> v i s i o n . r i g h t # same as v i s i o n [ 1 ] , b u t e x p l i c i t
8.8
>>> V i s i o n = namedtuple ( ’ V i s i o n ’ , [ ’ l e f t ’ , ’ combined ’ , ’ r i g h t ’ ] )
>>> v i s i o n = V i s i o n ( 9 . 5 , 9 . 2 , 8 . 8 )
>>> v i s i o n . l e f t # s t i l l c o r r e c t
9.5
>>> v i s i o n . r i g h t # s t i l l c o r r e c t ( t h o u g h now i s v i s i o n [ 2 ] )
8.8
>>> v i s i o n . combined # t h e new v i s i o n [ 1 ]
9.2

• defaultdict

21
– It allows you to avoid checking whether a key is in a dictionary
by simply inserting it for you on your first access attempt, with
a default value whose type you pass on creation.
– examples
# normal d i c t i o n a r y
>>> d = {}
>>> d [ ’ age ’ ] = d . g e t ( ’ age ’ , 0 ) + 1
>>> d
{ ’ age ’ : 1}
>>> d = { ’ age ’ : 39}
>>> d [ ’ age ’ ] = d . g e t ( ’ age ’ , 0 ) + 1
>>> d
{ ’ age ’ : 40}

# default dictionary
>>> from c o l l e c t i o n s import d e f a u l t d i c t
>>> dd = d e f a u l t d i c t ( int ) # i n t i s t h e d e f a u l t t y p e (0 t h e v a l u e )
>>> dd [ ’ age ’ ] += 1 # s h o r t f o r dd [ ’ age ’ ] = dd [ ’ age ’ ] + 1
>>> dd
d e f a u l t d i c t (< c l a s s ’ i n t ’ >, { ’ age ’ : 1 } ) # 1 , as e x p e c t e d

• ChainMap

– is provided for quickly linking a number of mappings so they can


be treated as a single unit
∗ example
>>> from c o l l e c t i o n s import ChainMap
>>> d e f a u l t _ c o n n e c t i o n = { ’ h o s t ’ : ’ l o c a l h o s t ’ , ’ p o r t ’ : 4567}
>>> c o n n e c t i o n = { ’ p o r t ’ : 5678}
>>> conn = ChainMap ( c o n n e c t i o n , d e f a u l t _ c o n n e c t i o n ) # map c r e a t i
>>> conn [ ’ p o r t ’ ] # p o r t i s found i n t h e f i r s t d i c t i o n a r y
5678
>>> conn [ ’ h o s t ’ ] # h o s t i s f e t c h e d from t h e second d i c t i o n a r y
’ localhost ’
>>> conn . maps # we can s e e t h e mapping o b j e c t s
[ { ’ port ’ : 5678} , { ’ host ’ : ’ l o c a l h o s t ’ , ’ port ’ : 4567}]
>>> conn [ ’ h o s t ’ ] = ’ packtpub . com ’ # l e t ’ s add h o s t
>>> conn . maps
[ { ’ p o r t ’ : 5 6 7 8 , ’ h o s t ’ : ’ packtpub . com ’ } ,

22
{ ’ host ’ : ’ l o c a l h o s t ’ , ’ port ’ : 4567}]
>>> del conn [ ’ p o r t ’ ] # l e t ’ s remove t h e p o r t i n f o r m a t i o n
>>> conn . maps
[ { ’ h o s t ’ : ’ packtpub . com ’ } , { ’ h o s t ’ : ’ l o c a l h o s t ’ , ’ p o r t ’ : 4 5 6 7 } ]
>>> conn [ ’ p o r t ’ ] # now p o r t i s f e t c h e d from t h e second d i c t i o n a r
4567
>>> dict ( conn ) # e a s y t o merge and c o n v e r t t o r e g u l a r d i c t i o n a r y
{ ’ h o s t ’ : ’ packtpub . com ’ , ’ p o r t ’ : 4567}

• Enums

– is a set of symbolic names (members) bound to unique, constant


values. Within an enumeration, the members can be compared
by identity, and the enumeration itself can be iterated over.
∗ example
>>> from enum import Enum
>>> c l a s s T r a f f i c L i g h t (Enum ) :
... GREEN = 1
... YELLOW = 2
... RED = 4
...
>>> T r a f f i c L i g h t .GREEN
<T r a f f i c L i g h t .GREEN: 1>
>>> T r a f f i c L i g h t .GREEN. name
’GREEN ’
>>> T r a f f i c L i g h t .GREEN. v a l u e
1
>>> T r a f f i c L i g h t ( 1 )
<T r a f f i c L i g h t .GREEN: 1>
>>> T r a f f i c L i g h t ( 4 )
<T r a f f i c L i g h t .RED: 4>

• Final Thoughts
# example customer o b j e c t s
customer1 = { ’ i d ’ : ’ abc123 ’ , ’ full_name ’ : ’ Master ␣Yoda ’ }
customer2 = { ’ i d ’ : ’ d e f 4 5 6 ’ , ’ full_name ’ : ’ Obi−Wan␣ Kenobi ’ }
customer3 = { ’ i d ’ : ’ g h i 7 8 9 ’ , ’ full_name ’ : ’ Anakin ␣ Skywalker ’ }
# collect them i n a t u p l e
customers = ( customer1 , customer2 , customer3 )

23
# or c o l l e c t them i n a l i s t
c u s t o m e r s = [ customer1 , customer2 , customer3 ]
# or maybe w i t h i n a d i c t i o n a r y , t h e y have a u n i q u e i d a f t e r a l l
customers = {
’ abc123 ’ : customer1 ,
’ d e f 4 5 6 ’ : customer2 ,
’ g h i 7 8 9 ’ : customer3 ,
}

4 Control Structures
4.1 Conditionals
• ==, !=, <, >, <=, >=

• the if statement
la t e = False
if late :
print ( ’ I ␣ need ␣ t o ␣ c a l l ␣my␣ manager ! ’ ) #1
else :
print ( ’ no␣ need ␣ t o ␣ c a l l ␣my␣ manager . . . ’ ) #2

• elif
income = 15000
i f income < 1 0 0 0 0 :
tax_coefficient = 0 . 0 #1
e l i f income < 3 0 0 0 0 :
tax_coefficient = 0 . 2 #2
e l i f income < 1 0 0 0 0 0 :
tax_coefficient = 0 . 3 5 #3
else :
tax_coefficient = 0 . 4 5 #4

• ternary operator
d i s c o u n t = 25 i f o r d e r _ t o t a l > 100 e l s e 0

24
4.2 for Loops
• for loops
fo r number in [ 0 , 1 , 2 , 3 , 4 ] :
print ( number )

#range f u n c t i o n c r e a t e s a L i s t
#range ( s t a r t , s t o p , s t e p )
#e . g . l i s t ( range ( 3 , 8 , 2 ) )
fo r number in range ( 5 ) :
print ( number )

surnames = [ ’ R i v e s t ’ , ’ Shamir ’ , ’ Adleman ’ ]


fo r p o s i t i o n in range ( len ( surnames ) ) :
print ( p o s i t i o n , surnames [ p o s i t i o n ] )

#or b e t t e r
fo r surname in surnames :
print ( surname )

4.3 Iterators and iterables


an iterable is: An object capable of returning its members one
at a time. Examples of iterables include all sequence types (such
as list, str, and tuple) and some non-sequence types like dict, file
objects, and objects of any classes you define with an __iter__()
method or with a __getitem__() method that implements Se-
quence semantics.
Iterables can be used in a for loop and in many other places
where a sequence is needed (zip(), map(), …). When an iterable
object is passed as an argument to the built-in function iter(), it
returns an iterator for the object. This iterator is good for one
pass over the set of values. When using iterables, it is usually
not necessary to call iter() or deal with iterator objects yourself.
The for statement does that automatically for you, creating a
temporary unnamed variable to hold the iterator for the duration
of the loop.

an iterator is: An object representing a stream of data. Repeated


calls to the iterator’s __next__() method (or passing it to the

25
built-in function next()) return successive items in the stream.
When no more data are available a StopIteration exception is
raised instead. At this point, the iterator object is exhausted
and any further calls to its __next__() method just raise Sto-
pIteration again. Iterators are required to have an __iter__()
method that returns the iterator object itself so every iterator
is also iterable and may be used in most places where other
iterables are accepted. One notable exception is code which at-
tempts multiple iteration passes. A container object (such as a
list) produces a fresh new iterator each time you pass it to the
iter() function or use it in a for loop. Attempting this with an
iterator will just return the same exhausted iterator object used
in the previous iteration pass, making it appear like an empty
container.

• Examples
# This works b u t not p y t h o n i c
p e o p l e = [ ’ Nick ’ , ’ Rick ’ , ’ Roger ’ , ’ Syd ’ ]
ages = [ 2 3 , 24 , 23 , 21]
fo r p o s i t i o n in range ( len ( p e o p l e ) ) :
person = people [ p o s i t i o n ]
age = a g e s [ p o s i t i o n ]
print ( person , age )

#b e t t e r b u t not q u i t e − we s t i l l have t o
#i n d e x
p e o p l e = [ ’ Nick ’ , ’ Rick ’ , ’ Roger ’ , ’ Syd ’ ]
ages = [ 2 3 , 24 , 23 , 21]
fo r p o s i t i o n , p e r s o n in enumerate ( p e o p l e ) :
age = a g e s [ p o s i t i o n ]
print ( person , age )

#b e t t e r − w i t h Zip
p e o p l e = [ ’ Nick ’ , ’ Rick ’ , ’ Roger ’ , ’ Syd ’ ]
ages = [ 2 3 , 24 , 23 , 21]
fo r person , age in zip ( p e o p l e , a g e s ) :
print ( person , age )

#Best
p e o p l e = [ ’ Nick ’ , ’ Rick ’ , ’ Roger ’ , ’ Syd ’ ]

26
ages = [ 2 3 , 24 , 23 , 21]
i n s t r u m e n t s = [ ’ Drums ’ , ’ Keyboards ’ , ’ Bass ’ , ’ G u i t a r ’ ]

#The f o r l o o p g e t a a s e q u e n c e o f t u p l e s
fo r person , age , i n s t r u m e n t in zip ( p e o p l e , ages , i n s t r u m e n t s ) :
print ( person , age , i n s t r u m e n t )

#This a l s o
ages = [ 2 3 , 24 , 23 , 21]
i n s t r u m e n t s = [ ’ Drums ’ , ’ Keyboards ’ , ’ Bass ’ , ’ G u i t a r ’ ]
fo r data in zip ( p e o p l e , ages , i n s t r u m e n t s ) :
p e o p l e = [ ’ Nick ’ , ’ Rick ’ , ’ Roger ’ , ’ Syd ’ ]
#e x p l o d e t h e s e q u e n c e i n s i d e t h e l o o p
person , age , i n s t r u m e n t = data
print ( person , age , i n s t r u m e n t )

4.4 while loops


• use a for loop when you need to iterate over an iterable, and a while
loop when you need to loop according to a condition being satisfied or
not.
• Example - Decimal to binary
#v e r s i o n one
n = 39
remainders = [ ]
while n > 0 :
re ma i n d e r = n % 2 # remainder o f d i v i s i o n by 2
r e m a i n d e r s . append ( r em a i n d e r ) # we k e e p t r a c k o f r e m a i n d e r s
n //= 2 # we d i v i d e n by 2

remainders . r e v e r s e ()
print ( r e m a i n d e r s )

#v e r s i o n two
n = 39
remainders = [ ]
while n > 0 :
n , r e m a i n d e r = divmod( n , 2 )
r e m a i n d e r s . append ( r em a i n d e r )

27
remainders . r e v e r s e ()
print ( r e m a i n d e r s )

#a n o t h e r example
p e o p l e = [ ’ Nick ’ , ’ Rick ’ , ’ Roger ’ , ’ Syd ’ ]
ages = [ 2 3 , 24 , 23 , 21]
position = 0
while p o s i t i o n < len ( p e o p l e ) :
person = people [ p o s i t i o n ]
age = a g e s [ p o s i t i o n ]
print ( person , age )
p o s i t i o n += 1

4.5 break and continue


• continue

from d a t e t i m e import date , t i m e d e l t a


today = d a t e . today ( )
tomorrow = today + t i m e d e l t a ( days =1) # t o d a y + 1 day i s tomorrow
products = [
{ ’ sku ’ : ’ 1 ’ , ’ e x p i r a t i o n _ d a t e ’ : today , ’ p r i c e ’ : 1 0 0 . 0 } ,
{ ’ sku ’ : ’ 2 ’ , ’ e x p i r a t i o n _ d a t e ’ : tomorrow , ’ p r i c e ’ : 5 0 } ,
{ ’ sku ’ : ’ 3 ’ , ’ e x p i r a t i o n _ d a t e ’ : today , ’ p r i c e ’ : 2 0 } ,
]

fo r pr o d u c t in p r o d u c t s :
i f p r o d u c t [ ’ e x p i r a t i o n _ d a t e ’ ] != today :
continue
pr o d u c t [ ’ p r i c e ’ ] ∗= 0 . 8 # e q u i v a l e n t t o a p p l y i n g 20% d i s c o u n t
print (
’ P r i c e ␣ f o r ␣ sku ’ , p r o d u c t [ ’ sku ’ ] ,
’ i s ␣now ’ , p r o d u c t [ ’ p r i c e ’ ] )

• break

i t e m s = [ 0 , None , 0 . 0 , True , 0 , 7 ]
# True and 7 e v a l u a t e t o True

28
found = F a l s e # t h i s i s c a l l e d ” f l a g ”
fo r item in i t e m s :
print ( ’ s c a n n i n g ␣ item ’ , item )
i f item :
found = True # we u p d a t e t h e f l a g
break
i f found : # we i n s p e c t t h e f l a g
print ( ’ At␣ l e a s t ␣ one ␣ item ␣ e v a l u a t e s ␣ t o ␣ True ’ )
else :
print ( ’ A l l ␣ i t e m s ␣ e v a l u a t e ␣ t o ␣ F a l s e ’ )

• A special else

– an else suite after a for or while loop. If the loop ends normally,
because of

exhaustion of the iterator (for loop) or because the condition is finally


not met (while loop), then the else suite (if present) is executed. If
execution is interrupted by a break statement, the else clause is not
executed.
#w i t h o u t t h e e l s e
class DriverException ( Exception ) :
pass

p e o p l e = [ ( ’ James ’ , 1 7 ) , ( ’ Kirk ’ , 9 ) , ( ’ Lars ’ , 1 3 ) , ( ’ Robert ’ , 8 ) ]


d r i v e r = None
fo r person , age in p e o p l e :
i f age >= 1 8 :
d r i v e r = ( person , age )
break
i f d r i v e r i s None :
r a i s e D r i v e r E x c e p t i o n ( ’ D r i v e r ␣ not ␣ found . ’ )

#w i t h t h e s p e c i a l e l s e
class DriverException ( Exception ) :
pass

p e o p l e = [ ( ’ James ’ , 1 7 ) , ( ’ Kirk ’ , 9 ) , ( ’ Lars ’ , 1 3 ) , ( ’ Robert ’ , 8 ) ]


fo r person , age in p e o p l e :
i f age >= 1 8 :

29
d r i v e r = ( person , age )
break
else :
r a i s e D r i v e r E x c e p t i o n ( ’ D r i v e r ␣ not ␣ found . ’ )

4.6 The walrus operator := a special assignment statement


• statements and expressions

A statement is: part of a suite (a “block” of code). A statement is


either an expression or one of several constructs with a keyword,
such as if, while or for.
An expression, on the other hand, is: A piece of syntax which
can be evaluated to some value. In other words, an expression
is an accumulation of expression elements like literals, names,
attribute access, operators or function calls which all return a
value.

• eg
re ma i n de r = v a l u e % modulus
i f re ma i n d e r :
print ( f ” Not␣ d i v i s i b l e ! ␣The␣ r e m a i n d e r ␣ i s ␣ { r e m a i n d e r } . ” )

i f re ma i n d e r := v a l u e % modulus : #s p e c i a l a s s i g n m e n t
print ( f ” Not␣ d i v i s i b l e ! ␣The␣ r e m a i n d e r ␣ i s ␣ { r e m a i n d e r } . ” )

#a n o t h e r example
f l a v o r s = [ ” p i s t a c h i o ” , ” malaga ” , ” v a n i l l a ” , ” c h o c o l a t e ” , ” s t r a w b e r r y ”
prompt = ” Choose ␣ your ␣ f l a v o r : ␣ ”
print ( f l a v o r s )
while ( c h o i c e := input ( prompt ) ) not in f l a v o r s :
print ( f ” Sorry , ␣ ’ { c h o i c e } ’ ␣ i s ␣ not ␣ a ␣ v a l i d ␣ o p t i o n . ” )
print ( f ”You␣ c h o s e ␣ ’ { c h o i c e } ’ . ” )

4.7 A few examples


• primes.py
pri me s = [ ] # t h i s w i l l c o n t a i n t h e primes a t t h e end
upto = 100 # t h e l i m i t , i n c l u s i v e

30
fo r n in range ( 2 , upto + 1 ) :
is_prime = True # f l a g , new a t each i t e r a t i o n o f o u t e r f o r
f or d i v i s o r in range ( 2 , n ) :
i f n % d i v i s o r == 0 :
is_prime = F a l s e
break
i f is_prime : # c h e c k on f l a g
p r i m e s . append ( n )
print ( p r i m e s )

#w i t h t h e s p e c i a l e l s e
# primes . e l s e . py
pri me s = [ ]
upto = 100
fo r n in range ( 2 , upto + 1 ) :
f or d i v i s o r in range ( 2 , n ) :
i f n % d i v i s o r == 0 :
break
else :
p r i m e s . append ( n )
print ( p r i m e s )

• coupons.py
customers = [
dict ( id =1, t o t a l =200 , coupon_code= ’ F20 ’ ) ,# F20 : f i x e d , £20
dict ( id =2, t o t a l =150 , coupon_code= ’ P30 ’ ) ,# P30 : p e r c e n t , 30%
dict ( id =3, t o t a l =100 , coupon_code= ’ P50 ’ ) ,# P50 : p e r c e n t , 50%
dict ( id =4, t o t a l =110 , coupon_code= ’ F15 ’ ) ,# F15 : f i x e d , £15
]

discounts = {
’ F20 ’ : ( 0 . 0 , 2 0 . 0 ) , # each v a l u e i s ( p e r c e n t , f i x e d )
’ P30 ’ : ( 0 . 3 , 0 . 0 ) ,
’ P50 ’ : ( 0 . 5 , 0 . 0 ) ,
’ F15 ’ : ( 0 . 0 , 1 5 . 0 ) ,
}

fo r customer in c u s t o m e r s :
code = customer [ ’ coupon_code ’ ]

31
p e r c e n t , f i x e d = d i s c o u n t s . g e t ( code , ( 0 . 0 , 0 . 0 ) ) #( 0 . 0 , 0 . 0 ) i s t h e
customer [ ’ d i s c o u n t ’ ] = p e r c e n t ∗ customer [ ’ t o t a l ’ ] + f i x e d #adds a

fo r customer in c u s t o m e r s :
print ( customer [ ’ i d ’ ] , customer [ ’ t o t a l ’ ] , customer [ ’ d i s c o u n t ’ ] )

4.8 The itertools module


• Infinite iterators
from i t e r t o o l s import count

#The c oun t f a c t o r y c l a s s makes an i t e r a t o r t h a t c o u n t s t o i n f i n i t y .


#I t s t a r t s from 5 and adds 3 each time
fo r n in count ( 5 , 3 ) :
i f n > 20:
break
print ( n , end= ’ , ␣ ’ ) # i n s t e a d o f n e w l i n e , comma and s p a c e

• Iterators terminating on the shortest input sequence

– create an iterator based on multiple iterators, combining their


values according to some logic. Among those iterators, if any of
them are shorter than the rest, the resulting iterator won’t break,
but will simply stop as soon as the shortest iterator is exhausted.
– Example
from i t e r t o o l s import compress

data = range ( 1 0 )
e v e n _ s e l e c t o r = [ 1 , 0 ] ∗ 10
o d d _ s e l e c t o r = [ 0 , 1 ] ∗ 10

even_numbers = l i s t ( compress ( data , e v e n _ s e l e c t o r ) )


odd_numbers = l i s t ( compress ( data , o d d _ s e l e c t o r ) )

print ( o d d _ s e l e c t o r )
print ( l i s t ( data ) )
print ( even_numbers )
print ( odd_numbers )

32
outputs:
[0 , 1, 0, 1, 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1]
[0 , 1, 2, 3, 4 , 5 , 6 , 7 , 8 , 9]
[0 , 2, 4, 6, 8]
[1 , 3, 5, 7, 9]

• Combinatoric Generators

– A permutation, also called an “arrangement number” or “order,”


is a rearrangement of the elements of an ordered list 𝑆 into a
one-to-one correspondence with 𝑆 itself.
– 𝑓 a set has 𝑁 elements, then the number of permutations of them
is 𝑁 ! (𝑁 factorial).
– Example:
from i t e r t o o l s import p e r m u t a t i o n s
print ( l i s t ( p e r m u t a t i o n s ( ’ABC ’ ) ) )

33

You might also like