Additional types of arguments in Python
Calls with multiple arguments
- Evaluation
12 + 7
19
- Console transcript
from operator import add
add( 12, 7 )
19
- Call (simplified)
expression .-----------------------------.
.------------. .-. | .------------. v .-.
--->| expression |--->( ( )---'---.--->| expression |---.---'--->( ) )--->
'------------' '-' ^ '------------' | '-'
| .-. |
'--------( , )--------'
'-'
Non-syntactical Requirements
The called object must be an object that can be called with the given number of arguments.
Semantics
Each argument is evaluated in turn and the the callee is called with the argument values.
Documentation
The number of parameters corresponds to the number of arguments. Please ignore », /« below.
- Console transcript (Python 3.7.0, alpha)
from operator import add
help( add )
Help on built-in function add in module _operator:
add(...)
add(a, b) -- Same as a + b.
- Console transcript (Python 3.7.0)
from operator import add
help( add )
Help on built-in function add in module _operator:
add(a, b, /)
Same as a + b.
Multiple print arguments
The arguments of ›print‹ are printed separated by a space.
- Console transcript
print( 'abc', 'def' )
abc def
- Console transcript
print( 'a', 1, True, None, -56 )
a 1 True None -56
Documentation of ›print‹
- Console transcript (simplified)
help( print )
print( value, ... )
The ellipsis »…« denotes an arbitrary number of arguments corresponding to the single parameter »value«.
The equals sign »=« and brackets (»[« and »]«) in the documentation
A default value of a parameter is a value that is taken as an argument value if no argument expression is specified for that parameter.
In case of the documentation of the function »log« from the module »math«, for example, the default value »math.e« is associated to the parameter »base«. This shows that the argument for this parameter is optional.
- Documentation of the log function from the math module
log(x, [base=math.e])
- Console transcript
from math import log
from math import e
log( e * e, e )
2.0
log( e * e )
2.0
log( 3 * 3 * 3 * 3, 3 )
4.0
Rule for exercises
From now on, all predefined names from the standard library may be used in solutions of exercises, if not stated otherwise in the task definition.
Exercises
Note to the instructor ► winsound follows
/ Exercise
Write a from import and a call to the function from the »math« module, the documentation of which is given below.
- documentation (reworked)
pow( x, y, / )
- x raised to the power of y
This task is considered correctly solved if the call to the function written can be evaluated by a Python implementation without error message.
/ Exercise ⃖
Try to output a sound using the module »winsound« (if you work with Windows ).
If you do not work with Windows, you might try to output a sound using Python, but this could be much harder.
Keyword arguments
»int«
- Evaluation
int( "20", 16 )
32
- Evaluation
int( "20", base=16 )
32
»base=16« is a keyword argument.
- Console transcript (simplified)
help( int )
int(x, base=10)
Keyword argument often cannot be used in calls of functions that were written in C (“built-in functions ”).
Wenn in der Dokumentation „eingebaut“ (»built-in«) fehlt, wurde die Funktion in Python programmiert. Dann können Kennwortargumente für alle Argumente verwendet werden.
The slash »/«
Parameters preceding a slash »/« in the documentation are positional-only parameters. Keyword arguments cannot be used for them.
- Console transcript
from math import sin
help( sin )
Help on built-in function sin in module math:
sin(x, /)
Return the sine of x (measured in radians).
sin( x=2 )
TypeError: sin() takes no keyword arguments
Keyword-only parameters
Some parameters take an arbitrary number of arguments, such as the value parameter of »print«. Keyword parameters following such parameters are keyword-only parameters, they must be used with keywords.
- Console transcript
help( print )
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
flush: whether to forcibly flush the stream.
In a call keyword arguments always follow positional arguments (arguments without a keyword).
»sep=«
- Console transcript
print( 'a', 1, True, None, -56, sep=', ' )
a, 1, True, None, -56
- Console transcript
print( 'a', 1, True, None, -56, sep='\n' )
a
1
True
None
-56
»sep« defaults to a space » «.
- Console transcript
print( 2, 2 )
2 2
- Console transcript
print( 2, 2, sep=" " )
2 2
»sorted«
»reverse«
- Console transcript
sorted( dir() )
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
sorted( dir(), True )
TypeError: sorted expected 1 argument, got 2
sorted( dir(), reverse=True )
['__spec__', '__package__', '__name__', '__loader__', '__doc__', '__builtins__', '__annotations__']
»key«
The keyword-only parameter »key« accepts a function by whose value the sorting is done.
- Console transcript
sorted( dir() )
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
sorted( dir(), key=len )
['__doc__', '__name__', '__spec__', '__loader__', '__package__', '__builtins__', '__annotations__']
sorted( dir(), key=len, reverse=True )
['__annotations__', '__builtins__', '__package__', '__loader__', '__name__', '__spec__', '__doc__']
sorted( dir(), key=lambda x: len( x ))
['__doc__', '__name__', '__spec__', '__loader__', '__package__', '__builtins__', '__annotations__']
sorted( dir(), key=lambda x: -len( x ))
['__annotations__', '__builtins__', '__package__', '__loader__', '__name__', '__spec__', '__doc__']
sorted( dir(), key=lambda x: x )
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
from random import random
sorted( dir(), key=lambda x: random() )
['__spec__', 'random', '__name__', '__loader__', '__doc__', '__annotations__', '__builtins__', '__package__']
sorted( dir(), key=lambda x: random() )
['__annotations__', '__package__', '__name__', '__spec__', '__doc__', '__builtins__', 'random', '__loader__']
»dict«
Two asterisk »**« indicate an arbitrary number of arguments with arbitrary keywords.
- Transcript (shortened)
help(dict)
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list. For example: dict(one=1, two=2)
In this way we can create custom dictionaries.
- Console transcript
dict()
{}
dict( a=1 )
{'a': 1}
dict( a=1, b=2 )
{'a': 1, 'b': 2}
»eval«
The eval function determines the value of an expression passed as a string.
- Console transcript
from math import pi
eval( "1 + pi" )
4.141592653589793
It also can use a dictionary to specify values of names.
- Console transcript
dict( a=1, b=2 )
{'a': 1, 'b': 2}
eval( "a + b", _ )
3
- Console transcript
eval( "a + b", dict( a=1, b=2 ))
3
- Console transcript
eval( "dir()", dict( a=1, b=2 ))
['__builtins__', 'a', 'b']
Practice questions ⃖
When answering, please spell out every character!
? Practice question ⃖
What output does the execution of the following statement produce?
- Statement
print()
? Practice question ⃖
What output does the execution of the following statement produce?
- Statement
print( ' ' )
? Practice question ⃖
What output does the execution of the following statement produce?
- Statement
print( ' ', sep=',' )
? Practice question ⃖
What output does the execution of the following statement produce?
- Statement
print( ',',',', sep=',' )
»issubclass«
»bool« is a subclass of »int«. We now also can confirm this using a call.
- Evaluation
1 + True
2
- Evaluation
issubclass
<built-in function issubclass>
- Evaluation
issubclass( bool, int )
True
- Evaluation
issubclass( int, bool )
False
An indentation error is a kind of syntax error.
- Evaluation
issubclass( IndentationError, SyntaxError )
True
Mapping callables to iterables
Using »map« a callable can be applied to any value yielded by an iterable. The ₍rɪˈzʌlt₎ result is then an iterable yielding the results of the applications (in the order that corresponds to the order of the original values).
In the following example we apply »sqrt« to each value yielded by »range( 3 )«.
- Console transcript
range( 3 )
range(0, 3)
tuple( _ )
(0, 1, 2)
from math import sqrt # Quadratwurzel
map( sqrt, _ )
<map object at 0x00000000023FD460>
tuple( _ )
(0.0, 1.0, 1.4142135623730951)
- Console transcript
from math import sqrt # Quadratwurzel
tuple( map( sqrt, range( 3 )))
(0.0, 1.0, 1.4142135623730951)
In the following example we apply »lambda i: i*i« to each value of »range( 10 )«.
- Console transcript
tuple( map( lambda i: i*i, range( 10 )))
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
To save time, »map« initially only returns an object that contains the results in descriptive form, without the expressions necessarily having actually been executed.
The following example shows that the expressions are evaluated only when they are really needed, for example, when the result is manifested as a tuple.
- Console transcript
map( print, dir() )
<map object at 0x0000000001D5AA00>
tuple( _ )
__annotations__
__builtins__
__doc__
__loader__
__name__
__package__
__spec__(None, None, None, None, None, None, None)
This also provides us with another possibility to output lists clearly arranged line by line!
A little later we will see how the output of the tuple ›(None, None, None, None, None, None, None, None)‹, which is of no interest to us, can be suppressed.
The following program applies the lambda function to each line entered. To terminate the input, Ctrl-Z is entered under Windows and Ctrl-D under Unix -like operating systems.
- Console transcript
list( map( lambda x: print( pow( int( x ), 2 )), stdin ))
2
4
9
81
^Z↵
[None, None]
A little later we will see how the output of the list ›[None, None])‹, which is of no interest to us, can be suppressed.
Exercises
/ Exercise
Warning The computer may become unresponsive if you make errors while trying to get this exercise done. It is important that the tuple is slowed down by the invocations of the print function so that the program can be aborted in time. If in doubt, use a web development environment for this exercise!
The call to »count« from the module »itertools« results in an iterable with all natural numbers in ascending order. Use ›tuple‹, ›map‹ and ›print‹ to output them! (This works as just shown for «dir()».)
- Start of the expected output
0
1
2
3
4
5
6
7
8
9
10
11
The evaluation causes a fast output of numbers that does not end by itself (an “endless loop”). Normally, however, the output can be stopped in time before the tuple becomes so large that the computer becomes unresponsive.
range objects with a start value
»range( start, top )« expresses a range object for the range of integral numbers starting at start «start» and up to – but excluding – «top».
- Evaluation
tuple( range( -3, 3 ))
(-3, -2, -1, 0, 1, 2)
- Evaluation
tuple( range( 3, -3 ))
()
- Evaluation
len( range( 3, -3 ))
0
- Evaluation
tuple( range( 3, 3 ))
()
range objects with a step value
»range( start, top, step )« expresses a range object for the range of integral numbers starting at start «start», up to – but excluding – «top», and with a step width of «step».
- Evaluation
tuple( range( 0, 10, 3 ))
(0, 3, 6, 9)
- Evaluation
len( range( 0, 10, 3 ))
4
- Evaluation
tuple( range( 10, 0, -1 ))
(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
- Evaluation
sorted( range( 10, 0, -1 ))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Attributes in Python
This section currently serves mainly as an outlook. Attribute accesses are rarely used in the further progress of this basic course and will only be taken up again and dealt with in more detail in the advanced course.
An object can contain attributes.
Each attribute is identified by its name and is bound to an object.
The names of the attributes of an object can be viewed using ›dir‹.
- Console transcript
import math
dir( math )
[… 'floor' … 'pi' … ]
Does the object »math« have an attribute »pi«?
- Evaluation
hasattr( math, 'pi' )
True
What is the object of the math attribute »pi«?
- Evaluation
getattr( math, 'pi' )
3.141592653589793
N.B.: »pi« was not imported.
- Console transcript
pi
NameError: name 'pi' is not defined
Call to the function »floor«, which in turn is expressed by a call to »getattr«.
- Console transcript
getattr( math, 'floor' )
<built-in function floor>
_( 22.7 )
22
- Evaluation
getattr( math, 'floor' )( 22.7 )
22
Call to a method of an str object.
- Evaluation
dir( 'abc' )
- [ … 'capitalize' … ]
So there is an attribute »capitalize« within the str object!
- Evaluation
getattr( 'abc', 'capitalize' )
<built-in method capitalize of str object …>
So the value of this attribute is a method! – A method is a callable!
So let's call it:
- Evaluation
_()
'Abc'
With a single evaluation:
- Evaluation
getattr( 'abc', 'capitalize' )()
'Abc'
Items in Python
This section also should be seen as an outlook, since in the basic course items are rarely used at present.
Besides attributes, an object can also contain items.
While the meaning of some attributes can be given by Python or its standard libraries, entries can be used more freely by their respective objects.
In the case of strings, items map numbers to the characters at the position given by the number.
- Console transcript
from operator import getitem
getitem( 'abc', 0 )
'a'
getitem( 'abc', 3 )
IndexError: string index out of range
getitem( 'abc', 2 )
'c'
getitem( 'abc', 1 )
'b'
len( 'abc' )
3
If an object supports »len« and »getitem«, on says it supports the sequence protocol. We might say that it is a sequence.
str objects do support the sequence protocol, int objects don't.
- Console transcript
from operator import getitem
getitem( 0, 0 )
TypeError: 'int' object is not subscriptable
len( 0 )
TypeError: object of type 'int' has no len()
»math« also supports »len« and »getitem«.
- Console transcript
from operator import getitem
import math
len( dir( math ))
60
getitem( dir( math ), 26 )
'floor'
Iterables
If a sequence is iterable, the item at position 0 usually is the same object as the first object yielded by an iterator for the sequence.
- Console transcript
from operator import getitem
next( iter( "xyzzy" ))
'x'
getitem( "xyzzy", 0 )
'x'
- Console transcript
from operator import getitem
dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
'x'
next( iter( dir() ))
'__annotations__'
getitem( dir(), 0 )
'__annotations__'
Counters
The individual items of a counter object can be retrieved using »getitem«.
- Console transcript
from collections import Counter
Counter( "beispielsweise" )
Counter({'e': 4, 'i': 3, 's': 3, 'b': 1, 'p': 1, 'l': 1, 'w': 1})
from operator import getitem
print( getitem( _, "e" ))
4
print( getitem( _, "i" ))
3
print( getitem( _, "w" ))
1
Dictionaries
The individual entries of a dictionary can be retrieved with »getitem«.
- Console transcript
dict( a=1, x="c" )
{'a': 1, 'x': 'c'}
from operator import getitem
getitem( _, "x" )
'c'
- Console transcript
from operator import getitem
getitem( dict( a=1, x="c" ), "x" )
'c'
Tuples
The individual entries of a tuple can be retrieved with »getitem«.
- Console transcript
range( 20, 30 )
range(20, 30)
tuple( _ )
(20, 21, 22, 23, 24, 25, 26, 27, 28, 29)
from operator import getitem
print( getitem( _, 0 ))
20
print( getitem( _, 9 ))
29
- Console transcript
from operator import getitem
getitem( tuple( range( 20, 30 )), 4 )
24
Lists
The individual entries of a tuple also can be retrieved with »getitem«.
- Console transcript
from operator import getitem
getitem( list( range( 20, 30 )), 4 )
24
Ranges
The individual entries of a range also can be retrieved with »getitem«.
The range specified in the transcript includes all values between 400000000000000000 (inclusive) and 900000000100000000 (exclusive) that can be obtained by repeatedly adding 321 to 400000000000000000.
- Console transcript
from operator import getitem
getitem( range( 400000000000000000, 900000000100000000, 321 ), 700000 )
400000000224700000
The huge range is not manifested, so the program hardly needs any memory! (If you try to manifest the range, the computer might crash).
Slices
Some objects also support slices, which can be used to express several entries at once. The arguments of ›slice‹ are: start value (inclusive), top value (=exclusive endvalue) and increment. Negative positions are counted from the end.
- Console transcript
from operator import getitem
getitem( 'abcdefghi', slice( 3, 6 ))
'def'
getitem( 'abcdefghi', slice( 6, 3, -1 ))
'gfe'
getitem( 'abcdefghi', slice( 2, 8, +2 ))
'cef'
getitem( 'abcdefghi', slice( 10, , -1 ))
'cef'
Callables for sequences
Some callables like »choice« are available for all sequences. »choice« randomly selects a value of the range. Again, despite the huge range, only very little memory is needed, because the range does not need to be manifested.
- Console transcript
from random import choice
choice( range( 400000000000000000, 900000000100000000, 321 ))
718379137792728649
That means: Whenever you want to select an entry at random from any sequence, you can use »choice« from now on! (It is only for practice purposes that sometimes you might be asked to use only »random«, and no other name from the random module).
/ Exercise
Write an expression that randomly selects a number between 1 (inclusive) and 6 (inclusive). Use »range« and »choice« for this.
Reversing sequences
- Evaluation
tuple( reversed( "beispielsweise" ))
('e', 's', 'i', 'e', 'w', 's', 'l', 'e', 'i', 'p', 's', 'i', 'e', 'b')
- Evaluation
tuple( reversed( dir() ))
('__spec__', '__package__', '__name__', '__loader__', '__doc__', '__builtins__', '__annotations__')
Multiparameter lambda expressions
Multiple parameter names (separated by commas) can be used as well. Each individual name may only occur once.
- Evaluation
( lambda x, y: x+y )( 7, 2 )
9
- Evaluation
( lambda x, y: x+y )( 'abc', 'def' )
'abcdef'
Example
We can separate the calculation rule from the data.
- Calculation of a BMI
( lambda mass, height: mass / height ** 2 )( 77, 1.73 )
25.727555214006482
- Calculation of a BMI
( lambda mass, height: mass / height ** 2 )( 78, 1.81 )
23.808797045267237
- Calculation of a BMI
( lambda mass, height: mass / height ** 2 )( 62.6, 1.68 )
22.179705215419506
Parameter names can be used for labeling.
- Calculation of a BMI
( lambda mass, height: mass / height ** 2 )( mass=62.6, height=1.68 )
22.179705215419506
Repeatable arguments
›min‹ can be called with two or more arguments.
- Evaluation
min( 9, 8 )
8
- Evaluation
min( 9, 8, 7 )
7
- Evaluation
min( 9, 8, 7, 2 )
2
»*args« in the proclamation shows that an arbitrary number or arguments is allowed at this place.
- Transcript (shortened and revised)
help( min )
Help on built-in function min in module builtins:
min( arg1, arg2, *args ) -> value
It reminds of »...« shown earlier.
- Transcript (revised, simplified, shortened)
help( print )
print( value, ... )
Exercises ⃗
/ Exercise ⃗
Write a call to the function »max« with two arguments, a call with three arguments, and a call with four arguments.
- Documentation (freely revised)
max( arg1, arg2, *args )
- The maximum of the argument values
Reduction of iterables
A reduction combines several values using a two-digit function.
- Console transcript
from functools import reduce
reduce( lambda x, y: x + ',' + y, 'ab' )
'a,b'
- Console transcript
from functools import reduce
reduce( lambda x, y: x + ',' + y, 'abc' )
'a,b,c'
- Console transcript
from functools import reduce
reduce( lambda x, y: x + ',' + y, 'a' )
'a'
- Console transcript
from functools import reduce
reduce( lambda x, y: x + ',' + y, '' )
TypeError: reduce() of empty sequence with no initial value
- Console transcript
from functools import reduce
reduce( lambda x, y: x + ',' + y, 'abcdef' )
'a,b,c,d,e,f'
- Console transcript
from functools import reduce
reduce( lambda x, y: x + y, range( 3 ))
3
reduce( lambda x, y: x + y, range( 5 ))
10
- Console transcript
from functools import reduce
from operator import add
reduce( add, range( 3 ))
3
reduce( add, range( 5 ))
10
- Another example *
from functools import reduce
reduce( lambda x, y: '(' + x + ',' + y +')', 'abc' )
'((a,b),c)'
reduce( lambda x, y: '(' + x + ',' + y +')', 'abcdef' )
'(((((a,b),c),d),e),f)'
Exercises
/ Exercise
Calculate the product of all natural numbers from 1 (inclusive) to 5 (inclusive) by calling »reduce« with »mul« (multiplication) from the operator module and a suitable call to ›range‹. The result should be «120».