Python Learning Course Session 1 —
Install windows Set the Add Python *.* to PATH
option during the installation process. linux/mac online interpreter Python2 vs Python3 Python3 history Python 3.0 - December 3, 2008 Python 3.1 - 2009 Python 3.2 - 2011 Python 3.3 - 2012 Python 3.4 - 2014 Python 3.5 - 2015 Python 3.6 - 2016 Python 3.7 - 2018 Python 3.8 - 2019 Python 3.9 - 2020 Key differences Python3 Pythom2 syntax is simpler and easily understandable. syntax is comparatively difficult to understand default storing of strings is Unicode define Unicode string value with “u.” value of variables never changes value of the global variable will be changed inside a for-loop exceptions, enclosed in parenthesis exceptions, enclosed in notations ordering comparisons are simplified rules of ordering comparison are complex offers Range() function to perform iterations the xrange() is used for iterations
Example:
# Python 3
print ( "Hello World!" )
# Python 2
print "Hello World!"
Python2 EOL (End of Life) 2020 Code Editors Python General Online Interpreter Python Cheat Sheets Primitive Datatypes and Operators Mathematical Operations # Numbers
3 # => 3
# Simple math
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
35 / 5 # => 7.0
#Integer division rounds down for both positive and negative numbers.
5 // 3 # => 1
- 5 // 3 # => -2
5.0 // 3.0 # => 1.0 # works on floats too
- 5.0 // 3.0 # => -2.0
# The result of division is always a float
10.0 / 3 # => 3.3333333333333335
# Modulo operation
7 % 3 # => 1
# i % j have the same sign as j, unlike C
- 7 % 3 # => 2
# Exponentiation (x**y, x to the yth power)
2 ** 3 # => 8
# Enforce precedence with parentheses
1 + 3 * 2 # => 7
( 1 + 3 ) * 2 # => 8
Variables There are no declarations, only assignments. Convention is to use lower_case_with_underscores
integer nunber = 5
number # => 5
# Define an integer in binry
number = 0b10
number # => 2
bin ( number ) # => 0b10
# Define an integer in hexadecimal
number = 0x10
number # => 16
hex ( number ) # => 0x10
Complex Numbers x = 0 + 1j
x * x # => (-1+0j)
string string = "I'm a string variable"
string # => "I'm a string variable"
string [ 0 ] # => "I"
string [ - 1 ] # => "e"
string [ 0 : 3 ] # => "I'm"
# Strings are created with " or '
"This is a string."
'This is also a string.'
# Strings can be added too
"Hello " + "world!" # => "Hello world!"
# String literals (but not variables) can be concatenated without
# using '+'
"Hello " "world!" # => "Hello world!"
# A string can be treated like a list of characters
"Hello world!" [ 0 ] # => 'H'
# You can find the length of a string
len ( "This is a string" ) # => 16
# You can also format using f-strings or formatted string literals
# (in Python 3.6+)
name = "Reiko"
f "She said her name is { name } ." # => "She said her name is Reiko"
# You can basically put any Python expression inside the braces and
# it will be output in the string.
f " { name } is { len ( name ) } characters long." # => "Reiko is 5
# characters long."
multi_line_string = """
First line
Second line
...
Last line
"""
multi_line_string # => '\nFirst line\nSecond line\n...\nLast line\n'
String Methods str . title ()
"""
Return a titlecased version of the string where words start with an
uppercase character and the remaining characters are lowercase.
"""
'Hello world' . title () # => 'Hello World'
str . strip ()
"""
Return a copy of the string with the leading and trailing characters
removed. The chars argument is a string specifying the set of
characters to be removed. If omitted or None, the chars argument
defaults to removing whitespace. The chars argument is not a
prefix or suffix; rather, all combinations of its
values are stripped.
"""
' spacious ' . strip () # => 'spacious'
'www.example.com' . strip ( 'cmowz.' ) # => 'example'
str . rstrip ()
"""
Return a copy of the string with trailing characters removed. The
chars argument is a string specifying the set of characters to be
removed. If omitted or None, the chars argument defaults to removing
whitespace. The chars argument is not a suffix; rather, all
combinations of its values are stripped.
"""
str . lstrip ()
"""
Return a copy of the string with leading characters removed. The
chars argument is a string specifying the set of characters to be
removed. If omitted or None, the chars argument defaults to removing
whitespace. The chars argument is not a prefix; rather, all
combinations of its values are stripped.
"""
str . find ( sub [, start [, end ]])
"""
Return the lowest index in the string where substring sub is found
within the slice s[start:end]. Optional arguments start and end are
interpreted as in slice notation. Return -1 if sub is not found.
"""
"""
Note The find() method should be used only if you need to know the
position of sub. To check if sub is a substring or not, use the in
operator:
"""
'Py' in 'Python' # => True
str . replace ( old , new [, count ])
"""
Return a copy of the string with all occurrences of substring old
replaced by new. If the optional argument count is given, only the
first count occurrences are replaced.
"""
str . lower ()
"""
Return a copy of the string with all the cased characters 4
converted to lowercase.
"""
str . upper ()
"""
Return a copy of the string with all the cased characters 4
converted to uppercase. Note that s.upper().isupper() might
be False if s contains uncased characters or if the Unicode
category of the resulting character(s) is not “Lu” (Letter,
uppercase), but e.g. “Lt” (Letter, titlecase).
"""
str . split ( sep = None , maxsplit =- 1 )
"""
Return a list of the words in the string, using sep as the delimiter string.
If maxsplit is given, at most maxsplit splits are done (thus, the list will
have at most maxsplit+1 elements). If maxsplit is not specified or -1, then
there is no limit on the number of splits (all possible splits are made).
If sep is given, consecutive delimiters are not grouped together and are deemed
to delimit empty strings (for example, '1,,2'.split(',') returns ['1', '', '2']).
The sep argument may consist of multiple characters (for example,
'1<>2<>3'.split('<>') returns ['1', '2', '3']). Splitting an empty string with a
specified separator returns [''].
"""
'1,2,3' . split ( ',' ) # => ['1', '2', '3']
'1,2,3' . split ( ',' , maxsplit = 1 ) # => ['1', '2,3']
'1,2,,3,' . split ( ',' ) # => ['1', '2', '', '3', '']
str . splitlines ([ keepends ])
"""
Return a list of the lines in the string, breaking at line boundaries. Line
breaks are not included in the resulting list unless keepends is given and true.
This method splits on the following line boundaries. In particular, the
boundaries are a superset of universal newlines.
Representation Description
-----------------------------===============
\n Line Feed
\r Carriage Return
\r\n Carriage Return + Line Feed
\v or \x0b Line Tabulation
\f or \x0c Form Feed
\x1c File Separator
\x1d Group Separator
\x1e Record Separator
\x85 Next Line (C1 Control Code)
\u2028 Line Separator
\u2029 Paragraph Separator
"""
sorted ( "This is a test string from Andrew" . split (), key = str . lower )
"""
# => ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
"""
float number = 45
real_number = 3.14159265359
Booleans and Logical operators Boolean values are primitives (Note: the capitalization)
True # => True
False # => False
# negate with not
not True # => False
not False # => True
# Boolean Operators
# Note "and" and "or" are case-sensitive
True and False # => False
False or True # => True
# True and False are actually 1 and 0 but with different keywords
True + True # => 2
True * 8 # => 8
False - 5 # => -5
# Comparison operators look at the numerical value of True and False
0 == False # => True
1 == True # => True
2 == True # => False
- 5 != False # => True
"""
Using boolean logical operators on ints casts them to booleans for
evaluation, but their non-cast value is returned
Don't mix up with bool(ints) and bitwise and/or (&,|)
"""
bool ( 0 ) # => False
bool ( 4 ) # => True
bool ( - 6 ) # => True
0 and 2 # => 0
- 5 or 0 # => -5
# Equality is ==
1 == 1 # => True
2 == 1 # => False
# Inequality is !=
1 != 1 # => False
2 != 1 # => True
# More comparisons
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# Seeing whether a value is in a range
1 < 2 and 2 < 3 # => True
2 < 3 and 3 < 2 # => False
# Chaining makes this look nicer
1 < 2 < 3 # => True
2 < 3 < 2 # => False
# (is vs. ==) is checks if two variables refer to the same object,
# but == checks if the objects pointed to have the same values.
a = 1
b = 1
b is a # => True, a and b refer to the same object
a = [ 1 , 2 , 3 , 4 ] # Point a at a new list, [1, 2, 3, 4]
b = a # Point b at what a is pointing to
b is a # => True, a and b refer to the same object
b == a # => True, a's and b's objects are equal
b = [ 1 , 2 , 3 , 4 ] # Point b at a new list, [1, 2, 3, 4]
b is a # => False, a and b do not refer to the same object
b == a # => True, a's and b's objects are equal
b is not a
"""
# =>
True, a's and b's objects are equal but a and b do
not refer to the same object
"""
# id(some_var) returns the address of the memory location that "some_var"
# references
# None is an object
None # => None
# Don't use the equality "==" symbol to compare objects to None
# Use "is" instead. This checks for equality of object identity.
"etc" is None # => False
None is None # => True
# None, 0, and empty strings/lists/dicts/tuples all evaluate to False.
# All other values are True
bool ( 0 ) # => False
bool ( "" ) # => False
bool ([]) # => False
bool ({}) # => False
bool (()) # => False
Convert Variable Types You can use type(variable) to get the type of variable.
string_as_float = float ( string )
real_number_as_int = int ( real_number )
number_as_bool = bool ( number )
boolean_as_str = str ( boolean )
print Function print ( "I'm Python. Nice to meet you!" ) # => I'm Python. Nice to meet you!
# By default the print function also prints out a newline at the end.
# Use the optional argument end to change the end string.
print ( "Hello, World" , end = "!" ) # => Hello, World!
Simple way to get input data from console
input_string_var = input ( "Enter some data: " ) # Returns the data as a string
Session 2 —
Linter A linter, is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs.
Pylint is a tool that checks for errors in Python code, tries to enforce a coding standard and looks for code smells. It can also look for certain type errors, it can recommend suggestions about how particular blocks can be refactored and can offer you details about the code’s complexity.
How to Write Beautiful Python Code. PEP 8 exists to improve the readability of Python code.
Source Code Encoding By default, Python source files are treated as encoded in UTF-8. In that encoding, characters of most languages in the world can be used simultaneously in string literals, identifiers and comments — although the standard library only uses ASCII characters for identifiers, a convention that any portable code should follow. To display all these characters properly, your editor must recognize that the file is UTF-8, and it must use a font that supports all the characters in the file.
# To declare that Windows-1252 encoding is to be used
# -*- coding: cp1252 -*-
Control Flow and Iterables Indentation is significant in Python! Convention is to use four spaces, not tabs.
if Statement # Here is an if statement.
# This prints "some_var is smaller than 10"
# In python "else if" is spelled "elif".
# Also, you need a colon after the elif and the else.
if some_var > 10 :
print ( "some_var is totally bigger than 10." )
elif some_var < 10 : # This elif clause is optional.
print ( "some_var is smaller than 10." )
else : # This is optional too.
print ( "some_var is indeed 10." )
# Putting a simple if-then-else statement on one line (Ternary Operator)
value_when_true if condition else value_when_false
body_temperature = 39
have_fever = True if body_temperature > 37 else False # => have_fever = True
for Loops # range(number)" returns an iterable of numbers
# from zero to the given number
for i in range ( 4 ):
print ( i )
"""
# =>
0
1
2
3
"""
# "range(lower, upper)" returns an iterable of numbers
# from the lower number to the upper number
for i in range ( 4 , 8 ):
print ( i )
"""
# =>
4
5
6
7
"""
# "range(lower, upper, step)" returns an iterable of numbers
# from the lower number to the upper number, while incrementing
# by step. If step is not indicated, the default value is 1.
for i in range ( 4 , 8 , 2 ):
print ( i )
"""
# =>
4
6
"""
print ( range ( 10 )) # => range(0, 10)
sum ( range ( 4 )) # => 0 + 1 + 2 + 3 = 6
list ( range ( 4 )) # => [0, 1, 2, 3]
type ( range ( 4 )) # => <class 'range'>
# To loop over a list, and retrieve both the index and the value of each item
# in the list
animals = [ "dog" , "cat" , "mouse" ]
for i , value in enumerate ( animals ):
print ( i , value )
"""
# =>
0 dog
1 cat
2 mouse
"""
# For loops iterate over lists
for animal in [ "dog" , "cat" , "mouse" ]:
# You can use format() to interpolate formatted strings
print ( "{} is a mammal" . format ( animal ))
"""
# =>
dog is a mammal
cat is a mammal
mouse is a mammal
"""
# Code that modifies a collection while iterating over that same collection
# can be tricky to get right. Instead, it is usually more straight-forward
# to loop over a copy of the collection or to create a new collection.
# Strategy: Iterate over a copy
for user , status in users . copy (). items ():
if status == 'inactive' :
del users [ user ]
# Strategy: Create a new collection
active_users = {}
for user , status in users . items ():
if status == 'active' :
active_users [ user ] = status
# To iterate over the indices of a sequence, you can combine range() and len().
a = [ 'Mary' , 'had' , 'a' , 'little' , 'lamb' ]
for i in range ( len ( a )):
print ( i , a [ i ])
"""
# =>
0 Mary
1 had
2 a
3 little
4 lamb
"""
while Loops # While loops go until a condition is no longer met.
x = 0
while x < 4 :
print ( x )
x += 1 # Shorthand for x = x + 1
"""
#+>
0
1
2
3
"""
# An initial sub-sequence of the Fibonacci series.
a , b = 0 , 1
while a < 1000 :
print ( a , end = ',' )
a , b = b , a + b
# => 0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
break and continue Statements, and else Clauses on Loops The break statement, breaks out of the innermost enclosing for or while loop. Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the iterable (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.
# This is exemplified by the following loop, which
# searches for prime numbers.
for n in range ( 2 , 10 ):
for x in range ( 2 , n ):
if n % x == 0 :
print ( n , 'equals' , x , '*' , n // x )
break
else : # else clause belongs to the for loop, not the if statement.
# loop fell through without finding a factor
print ( n , 'is a prime number' )
"""
=>
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
"""
# Like break, the continue statement, also borrowed from C, continues with the
# next iteration of the loop.
for num in range ( 2 , 10 ):
if num % 2 == 0 :
print ( "Found an even number" , num )
continue
print ( "Found a number" , num )
"""
=>
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9
"""
Iterable Object Python offers a fundamental abstraction called the Iterable. An iterable is an object that can be treated as a sequence. The object returned by the range function, is an iterable.
filled_dict = { "one" : 1 , "two" : 2 , "three" : 3 }
our_iterable = filled_dict . keys ()
print ( our_iterable ) # => dict_keys(['one', 'two', 'three']).
# This is an object that implements our
# Iterable interface.
# We can loop over it.
for i in our_iterable :
print ( i ) # Prints one, two, three
# However we cannot address elements by index.
our_iterable [ 1 ] # Raises a TypeError
# An iterable is an object that knows how to create an iterator.
our_iterator = iter ( our_iterable )
"""
Our iterator is an object that can remember the state as we
traverse through it.
We get the next object with "next()".
"""
next ( our_iterator ) # => "one"
# It maintains state as we iterate.
next ( our_iterator ) # => "two"
next ( our_iterator ) # => "three"
# After the iterator has returned all of its data, it raises a
# StopIteration exception
next ( our_iterator ) # Raises StopIteration
# We can also loop over it, in fact, "for" does this implicitly!
our_iterator = iter ( our_iterable )
for i in our_iterator :
print ( i ) # Prints one, two, three
# You can grab all the elements of an iterable or iterator by
# calling list() on it.
list ( our_iterable ) # => Returns ["one", "two", "three"]
list ( our_iterator ) # => Returns [] because state is saved
Session 3 —
Handling Exceptions It is possible to write programs that handle selected exceptions. Look at the following example, which asks the user for input until a valid integer has been entered, but allows the user to interrupt the program (using Control-C or whatever the operating system supports); note that a user-generated interruption is signalled by raising the KeyboardInterrupt exception.
Built-in Exceptions Description ArithmeticError Raised when an error occurs in numeric calculations AssertionError Raised when an assert statement fails AttributeError Raised when attribute reference or assignment fails Exception Base class for all exceptions EOFError Raised when the input() method hits an “end of file” condition (EOF) FloatingPointError Raised when a floating point calculation fails GeneratorExit Raised when a generator is closed (with the close() method) ImportError Raised when an imported module does not exist IndentationError Raised when indendation is not correct IndexError Raised when an index of a sequence does not exist KeyError Raised when a key does not exist in a dictionary KeyboardInterrupt Raised when the user presses Ctrl+c, Ctrl+z or Delete LookupError Raised when errors raised cant be found MemoryError Raised when a program runs out of memory NameError Raised when a variable does not exist NotImplementedError Raised when an abstract method requires an inherited class to override the method OSError Raised when a system related operation causes an error OverflowError Raised when the result of a numeric calculation is too large ReferenceError Raised when a weak reference object does not exist RuntimeError Raised when an error occurs that do not belong to any specific expections StopIteration Raised when the next() method of an iterator has no further values SyntaxError Raised when a syntax error occurs TabError Raised when indentation consists of tabs or spaces SystemError Raised when a system error occurs SystemExit Raised when the sys.exit() function is called TypeError Raised when two different types are combined UnboundLocalError Raised when a local variable is referenced before assignment UnicodeError Raised when a unicode problem occurs UnicodeEncodeError Raised when a unicode encoding problem occurs UnicodeDecodeError Raised when a unicode decoding problem occurs UnicodeTranslateError Raised when a unicode translation problem occurs ValueError Raised when there is a wrong value in a specified data type ZeroDivisionError Raised when the second operator in a division is zero
while True :
try :
x = int ( input ( "Please enter a number: " ))
break
except ValueError :
print ( "Oops! That was no valid number. Try again..." )
# Handle exceptions with a try/except block
try :
# Use "raise" to raise an error
raise IndexError ( "This is an index error" )
except IndexError as e :
pass # Pass is just a no-op. Usually you would do recovery here.
except ( RuntimeError , TypeError , NameError , ValueError ):
pass # Multiple exceptions can be handled together, if required.
else : # Optional clause to the try/except block. Must follow all except blocks
print ( "All good!" ) # Runs only if the code in try raises no exceptions
finally : # Execute under all circumstances
print ( "We can clean up resources here" )
Session 4 —
Functions Create A Function # Use "def" to create new functions
def add ( x , y ):
print ( "x is {} and y is {}" . format ( x , y ))
return x + y # Return values with a return statement
# Calling functions with parameters
add ( 5 , 6 ) # => prints out "x is 5 and y is 6" and returns 11
# Another way to call functions is with keyword arguments
add ( y = 6 , x = 5 ) # Keyword arguments can arrive in any order.
Procedures and Functions """
Write Fibonacci series up to n (as a procedure)
The first statement of the function body can optionally be a string
literal; this string literal is the function’s documentation string,
or docstring.
"""
def fib ( n ):
"""Print a Fibonacci series up to n."""
a , b = 0 , 1
while a < n :
print ( a , end = ' ' )
a , b = b , a + b
print ()
# Now call the function we just defined:
fib ( 2000 ) # => 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
# You can assign the function name to another name which can then
# also be used as a function. This serves as a general renaming mechanism:
fib # => <function fib at 10042ed0>
f = fib
f ( 100 ) # => 0 1 1 2 3 5 8 13 21 34 55 89
# The difference between Procedures and Functions:
# Even functions without a return statement do return the None value.
print ( fib ( 0 )) # => None
# A function that returns a list of the numbers of the Fibonacci series,
# instead of printing it
def fib2 ( n ): # return Fibonacci series up to n
"""Return a list containing the Fibonacci series up to n."""
result = []
a , b = 0 , 1
while a < n :
result . append ( a ) # see below
a , b = b , a + b
return result
f100 = fib2 ( 100 ) # call it
# write the result
f100 # => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Positional Arguments And Keyword Arguments You can define functions that take a variable number of positional arguments or using keyword arguments of the form kwarg=value. You can also define functions that take a variable number of keyword arguments, as well.
def varargs ( * args ):
return args
varargs ( 1 , 2 , 3 ) # => (1, 2, 3)
def keyword_args ( ** kwargs ):
return kwargs
# Let's call it to see what happens
keyword_args ( big = "foot" , loch = "ness" )
# => {"big": "foot", "loch": "ness"}
# You can do both at once, if you like
def all_the_args ( * args , ** kwargs ):
print ( args )
print ( kwargs )
"""
all_the_args(1, 2, a=3, b=4) prints:
(1, 2)
{"a": 3, "b": 4}
"""
# When calling functions, you can do the opposite of args/kwargs!
# Use * to expand tuples and use ** to expand kwargs.
args = ( 1 , 2 , 3 , 4 )
kwargs = { "a" : 3 , "b" : 4 }
all_the_args ( * args )
# equivalent to all_the_args(1, 2, 3, 4)
all_the_args ( ** kwargs )
# equivalent to all_the_args(a=3, b=4)
all_the_args ( * args , ** kwargs )
# equivalent to all_the_args(1, 2, 3, 4, a=3, b=4)
def parrot ( voltage , state = 'a stiff' , action = 'voom' , type = 'Norwegian Blue' ):
print ( "-- This parrot wouldn't" , action , end = ' ' )
print ( "if you put" , voltage , "volts through it." )
print ( "-- Lovely plumage, the" , type )
print ( "-- It's" , state , "!" )
# Valid way of calling parrot function
# 1 positional argument
parrot ( 1000 )
# 1 keyword argument
parrot ( voltage = 1000 )
# 2 keyword arguments
parrot ( voltage = 1000000 , action = 'VOOOOOM' )
# 2 keyword arguments
parrot ( action = 'VOOOOOM' , voltage = 1000000 )
# 3 positional arguments
parrot ( 'a million' , 'bereft of life' , 'jump' )
# 1 positional, 1 keyword
parrot ( 'a thousand' , state = 'pushing up the daisies' )
# The following calls would be invalid
# required argument missing
parrot ()
# non-keyword argument after a keyword argument
parrot ( voltage = 5.0 , 'dead' )
# duplicate value for the same argument
parrot ( 110 , voltage = 220 )
# unknown keyword argument
parrot ( actor = 'John Cleese' )
Default Argument Values def ask_ok ( prompt , retries = 4 , reminder = 'Please try again!' ):
while True :
ok = input ( prompt )
if ok in ( 'y' , 'ye' , 'yes' ):
return True
if ok in ( 'n' , 'no' , 'nop' , 'nope' ):
return False
retries = retries - 1
if retries < 0 :
raise ValueError ( 'invalid user response' )
print ( reminder )
# This function can be called in several ways:
ask_ok ( 'Do you really want to quit?' )
ask_ok ( 'OK to overwrite the file?' , 2 )
ask_ok ( 'OK to overwrite the file?' , 2 , 'Come on, only yes or no!' )
The default values are evaluated at the point of function definition in the defining scope. Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes.
i = 5
def f ( arg = i ):
print ( arg )
i = 6
f () # => 5
"""
The following function accumulates the arguments passed to it on
subsequent calls:
"""
def f ( a , L = []):
L . append ( a )
return L
print ( f ( 1 )) # => [1]
print ( f ( 2 )) # => [1, 2]
print ( f ( 3 )) # => [1, 2, 3]
"""
If you don’t want the default to be shared between subsequent
calls, you can write the function like this instead:
"""
def f ( a , L = None ):
if L is None :
L = []
L . append ( a )
return L
print ( f ( 1 )) # => [1]
print ( f ( 2 )) # => [2]
print ( f ( 3 )) # => [3]
Special Parameters def f ( pos1 , pos2 , / , pos_or_kwd , * , kwd1 , kwd2 ):
# ----------- ---------- ----------
# | | |
# | Positional or keyword |
# | - Keyword only
# -- Positional only
def standard_arg ( arg ):
print ( arg )
def pos_only_arg ( arg , / ):
print ( arg )
def kwd_only_arg ( * , arg ):
print ( arg )
def combined_example ( pos_only , / , standard , * , kwd_only ):
print ( pos_only , standard , kwd_only )
pos_only_arg ( 1 ) # => 1
pos_only_arg ( arg = 1 )
"""
# =>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pos_only_arg() got an unexpected keyword argument 'arg'
"""
kwd_only_arg ( 3 )
"""
# =>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given
"""
kwd_only_arg ( arg = 3 ) # => 3
combined_example ( 1 , 2 , 3 )
"""
# =>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: combined_example() takes 2 positional arguments but 3 were given
"""
combined_example ( 1 , 2 , kwd_only = 3 ) # => 1 2 3
combined_example ( 1 , standard = 2 , kwd_only = 3 ) # =>1 2 3
combined_example ( pos_only = 1 , standard = 2 , kwd_only = 3 )
"""
# =>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: combined_example() got an unexpected keyword argument 'pos_only'
"""
# Collision between the positional argument name and **kwds
# which has name as a key
def foo ( name , ** kwds ):
return 'name' in kwds
foo ( 1 , ** { 'name' : 2 })
"""
# =>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for argument 'name'
"""
# Using / (positional only arguments), it is possible since it allows
# name as a positional argument and
# 'name' as a key in the keyword arguments:
def foo ( name , / , ** kwds ):
return 'name' in kwds
foo ( 1 , ** { 'name' : 2 }) # => True
Unpacking Argument Lists # normal call with separate arguments
list ( range ( 3 , 6 )) # =>[3, 4, 5]
# call with arguments unpacked from a list
args = [ 3 , 6 ]
list ( range ( * args )) # => [3, 4, 5]
# In the same fashion, dictionaries can deliver keyword arguments
# with the **-operator.
def parrot ( voltage , state = 'a stiff' , action = 'voom' ):
print ( "-- This parrot wouldn't" , action , end = ' ' )
print ( "if you put" , voltage , "volts through it." , end = ' ' )
print ( "E's" , state , "!" )
d = { "voltage" : "four million" , "state" : "bleedin' demised" , "action" : "VOOM" }
parrot ( ** d )
"""
# =>
-- This parrot wouldn't VOOM if you put four million volts through
it. E's bleedin' demised !
"""
Returning Multiple Values (with tuple assignments) def swap ( x , y ):
return y , x
"""
Return multiple values as a tuple without the parenthesis.
(Note: parenthesis have been excluded but can be included)
"""
x = 1
y = 2
x , y = swap ( x , y ) # => x = 2, y = 1
# (x, y) = swap(x,y) # Again parenthesis have been excluded but can
# be included.
Function Scope x = 5
def set_x ( num ):
# Local var x not the same as global variable x
x = num # => 43
( print )( x ) # => 43
def set_global_x ( num ):
global x
print ( x ) # => 5
x = num # global var x is now set to 6
print ( x ) # => 6
set_x ( 43 )
set_global_x ( 6 )
First Class And Anonymous Functions # Python has first class functions
def create_adder ( x ):
def adder ( y ):
return x + y
return adder
add_10 = create_adder ( 10 )
add_10 ( 3 ) # => 13
# There are also anonymous functions
( lambda x : x > 2 )( 3 ) # => True
( lambda x , y : x ** 2 + y ** 2 )( 2 , 1 ) # => 5
# Sort a list of tuples by 2nd item.
pairs = [( 1 , 'one' ), ( 2 , 'two' ), ( 3 , 'three' ), ( 4 , 'four' )]
pairs . sort ( key = lambda pair : pair [ 1 ])
pairs # => [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
# Using itemgetter(1), which is essentially a faster version of
# lambda x: x[1], for optimization.
from operator import itemgetter
data = [( 1 , 'one' ), ( 2 , 'two' ), ( 3 , 'three' ), ( 4 , 'four' )]
sorted ( data , key = itemgetter ( 1 ))
# => [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
Using itemgetter
is more readable in this case than the solution by lambda
. It is also faster since almost all of the computation will be done on the c
side (no pun intended) rather than through the use of lambda
.
$ python -m timeit -s "from operator import itemgetter; data = [(1, 'one'), (
2, 'two'), (3, 'three'), (4, 'four')]" "sorted(data,key=itemgetter(1))"
500000 loops, best of 5: 645 nsec per loop
$ python -m timeit -s "data = [(1, 'one'), (2, 'two'), (3, 'three'), (
4, 'four')]" "sorted(data,key=lambda x: x[1])"
500000 loops, best of 5: 846 nsec per loop
List And Dictionary Comprehensions # There are built-in higher order functions
list ( map ( add_10 , [ 1 , 2 , 3 ])) # => [11, 12, 13]
list ( map ( max , [ 1 , 2 , 3 ], [ 4 , 2 , 1 ])) # => [4, 2, 3]
list ( filter ( lambda x : x > 5 , [ 3 , 4 , 5 , 6 , 7 ])) # => [6, 7]
# We can use list comprehensions for nice maps and filters
# List comprehension stores the output as a list which can itself be
# a nested list
[ add_10 ( i ) for i in [ 1 , 2 , 3 ]] # => [11, 12, 13]
[ x for x in [ 3 , 4 , 5 , 6 , 7 ] if x > 5 ] # => [6, 7]
# You can construct set and dict comprehensions as well.
{ x for x in 'abcddeef' if x not in 'abc' } # => {'d', 'e', 'f'}
{ x : x ** 2 for x in range ( 5 )} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# Lists to represent keys and values
keys = [ 'a' , 'b' , 'c' , 'd' , 'e' ]
values = [ 1 , 2 , 3 , 4 , 5 ]
# but this line shows dict comprehension here
myDict = { k : v for ( k , v ) in zip ( keys , values )}
# We can use below too
# myDict = dict(zip(keys, values))
print ( myDict ) # => {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# Initialize fahrenheit dictionary
fahrenheit = { 't1' : - 30 , 't2' : - 20 , 't3' : - 10 , 't4' : 0 }
# Get the corresponding celsius values
celsius = list ( map ( lambda x : ( float ( 5 ) / 9 ) * ( x - 32 ), fahrenheit . values ()))
# Create the celsius dictionary
celsius_dict = dict ( zip ( fahrenheit . keys (), celsius ))
print ( celsius_dict )
"""
# => {'t2': -28.88888888888889, 't3': -23.333333333333336,
't1': -34.44444444444444, 't4': -17.77777777777778}
"""
# Or you can use the .items method
celsius = { k :( float ( 5 ) / 9 ) * ( v - 32 ) for ( k , v ) in fahrenheit . items ()}
# Dictionary comprehensions with if and else statements and
# with other expressions
newdict = { x : x ** 3 for x in range ( 10 ) if x ** 3 % 4 == 0 }
print ( newdict ) # => {0: 0, 8: 512, 2: 8, 4: 64, 6: 216}
Function Annotations Annotations are stored in the annotations attribute of the function as a dictionary and have no effect on any other part of the function.
def f ( ham : str , eggs : str = 'eggs' ) -> str :
print ( "Annotations:" , f . __annotations__ )
print ( "Arguments:" , ham , eggs )
return ham + ' and ' + eggs
f ( 'spam' )
"""
# =>
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs
"""
Read/Write From/To A File with open ( "myfile.txt" ) as f :
for line in f :
print ( line )
# Writing to a file
contents = { "aa" : 12 , "bb" : 21 }
with open ( "myfile1.txt" , "w+" ) as file :
file . write ( str ( contents )) # writes a string to a file
with open ( "myfile2.txt" , "w+" ) as file :
file . write ( json . dumps ( contents )) # writes an object to a file
# Reading from a file
with open ( 'myfile1.txt' , "r+" ) as file :
contents = file . read () # reads a string from a file
print ( contents )
# print: {"aa": 12, "bb": 21}
with open ( 'myfile2.txt' , "r+" ) as file :
contents = json . load ( file ) # reads a json object from a file
print ( contents )
# print: {"aa": 12, "bb": 21}