Python Core Concepts

Python 3 programming fundamentals

Get Started. It's Free
or sign up with your email address
Python Core Concepts by Mind Map: Python Core Concepts

1. Python variables

1.1. Python variable naming rules

1.1.1. upper/lower case letters, digits and underscore (_)

1.1.2. must begin with letter or underscore (_)

1.1.3. Python is case sensitive

1.1.4. cannot conflict with Python reserved words

1.1.4.1. Python reserved keywords

1.1.5. letters from non Latin alphabets also allowed

1.1.6. same naming rules apply to functions

1.2. Python variable declaration and assignment

1.2.1. var = val

1.2.2. you can also make multiple assignments in single line

1.2.2.1. example

1.2.2.1.1. a, b, c = 1, 3, 7

1.2.3. you can reverse variable assignments in single line

1.2.3.1. example

1.2.3.1.1. var1, var2 = var2, var1

1.2.4. you can also assign two or more variables to a single value in one line

1.2.4.1. example

1.2.4.1.1. var1 = var2 = 1

1.3. Python assignments and shortcut operators

1.3.1. Examples: += and -=

1.4. Python is dynamically typed

1.4.1. no need to declare type

1.4.2. re-assignment to different types allowed

2. Python data types

2.1. Python literal values

2.1.1. Python octal numbers

2.1.1.1. 0o prefix

2.1.2. Python hexadecimal numbers

2.1.2.1. 0x prefix

2.1.3. Python floating point numbers

2.1.3.1. Python number scientific notation

2.1.3.1.1. For very big or small numbers

2.1.3.1.2. exponent + 'E' + base

2.1.4. Python Booleans

2.2. Python strings

2.2.1. Python string escape characters

2.2.1.1. starts with \

2.2.1.1.1. example

2.2.2. Python multiline strings

2.2.2.1. """line 1 line 2"""

2.3. Python integers

3. Python PEP 8 style guide

3.1. Recommended standards for Python code style

4. Python type cast functions

4.1. Python int() function

4.2. Python float() function

4.3. Python str() function

5. Python string replication

5.1. string * 5

6. Python loops

6.1. Python while loop

6.1.1. while condition_expression: <instruction(s)>

6.1.2. if condition is false on first evaluation, loop body is not executed even once

6.1.3. loop body should include instruction(s) that eventually change while loop's condition expression to False

6.1.4. If loop body never alters condition expression from True to False, you get an endless loop

6.1.4.1. Ctrl + C usually breaks out of endless loop

6.2. instructions in loop are called loop's body

6.3. Python for loop

6.3.1. for <control variable> in <collection>: <instruction(s)>

6.3.2. number of elements in collection determines loop repetitions

6.3.3. control variable is fed next collection element on each loop

6.4. Python break and continue

6.4.1. break halts loop and exits it

6.4.2. continue halts loop body and jumps to next iteration

6.5. else clause supported for both while and for

6.5.1. always runs exactly once even when main loop body does not run at all

7. Python bitwise operators

7.1. &

7.1.1. bitwise conjunction

7.1.2. requires exactly two 1s to return 1, else 0

7.2. |

7.2.1. bitwise disjunction

7.2.2. requires at least one 1 to return 1, else 0

7.3. ~

7.3.1. bitwise negation

7.3.2. turns 1 to 0 and 0 to 1

7.4. ^

7.4.1. bitwise exclusive or (xor)

7.4.2. requires exactly one 1 to return 1, else 0

7.5. & | ^ have higher precedence than assignment operators but lower than comparison operators

7.6. Python shift operators

7.6.1. <<

7.6.1.1. left shift

7.6.1.1.1. example

7.6.2. >>

7.6.2.1. right shift

7.6.2.1.1. example

7.6.3. higher precedence than comparison operators, lower than binary arithmetic operators

7.7. arguments must be integers, floats are disallowed

7.8. unlike logical operators, bitwise operators act on individual bits of arguments

7.9. assignments, long and abbreviated

7.9.1. x = x & y

7.9.1.1. x &= y

7.9.2. x = x | y

7.9.2.1. x |= y

7.9.3. x = x ^ y

7.9.3.1. x ^= y

7.10. lowest bit is named bit number 0, second bit is bit #1, etc

7.11. bitmasks to check, reset and set bits

7.11.1. check bit (is set to 1)

7.11.1.1. if flagRegister & theMask: # my bit is set else: # my bit is reset

7.11.2. reset bit (to zero)

7.11.2.1. flagRegister = flagRegister & ~theMask

7.11.3. set bit (to 1)

7.11.3.1. flagRegister = flagRegister | theMask

7.12. Binary manipulation

8. Python methods

8.1. like function but dependent on class (object)

8.2. invocation differs to function

8.2.1. object.method()

8.3. can alter internal state of object

9. Python None value

9.1. None is a reserved keyword

9.2. you can assign to a variable or return it from an invoked function

9.3. assigning a variable to a function that doesn't include a return will assign None to that variable

10. Python backslash \ to break long lines of code

10.1. example

10.1.1. print("This is a really long line \ but we can split it over multiple lines to improve readability")

11. Python sequences

11.1. collections that have a fixed ordering to their elements

11.2. can be iterated over by a for loop

12. Multiple versions of Python

12.1. Python language was created by Guido van Rossum and first released in 1991

12.1.1. Guido is President of the Python Software Foundation (PSF)

12.1.1.1. PSF official website is python.org

12.2. Python 2 and Python 3 are two active versions that are not compatible with one another

12.2.1. Python 3 first released in 2008 is a major revision of the language

12.2.1.1. there are multiple dot releases for Python 3, which are fully backward compatible within the Python 3 family of versions

12.2.2. Python 2 development cycle ended quite some time ago, but continued to receive bug fixes, security enhancements, etc for many years

12.2.2.1. 1st Jan 2020 was Python 2 official sunset date, set by the PSF

12.2.2.1.1. Post sunset, Python 2 is officially no longer supported - no more bug fixes or security enhancements - users are urged to complete transition to Python 3

12.3. In addition to Python 2 and Python 3, there is more than one version of each

12.3.1. Pythons developed and maintained by people working under umbrella of PSF are known as canonical or reference versions - this is because Guido is President of PSF

12.3.1.1. these official versions of Python are also known as CPython

12.3.1.1.1. All versions of CPython are developed using the C language

12.3.1.1.2. Virtually all platforms have built in support for compiling and running C programs, which makes CPython highly portable across platforms

12.3.2. Cython is a Python superset that is intended to solve one of CPython's weaknesses, which is relatively slow performance (because CPython is an interpreted language)

12.3.2.1. Cython automatically translates Python code into C and in doing so makes the code significantly faster to execute

12.3.3. Jython is a version of Python developed in Java rather than C

12.3.3.1. useful for large & complex systems developed entirely with Java that need Python flexibility added

12.3.3.2. Java and C have little in common, which can make integrating CPython into Java environments difficult

12.3.3.3. Jython conforms to Python 2 standards, but does not yet support Python 3

12.3.4. PyPy is a version of Python developed in RPython

12.3.4.1. RPython stands for Restricted Python, which is a subset of CPython

12.3.4.2. Like Cython, PyPy translates Python code into C before execution, thereby making for faster code execution

12.3.4.3. PyPy is mostly used by developers that are developing the Python language itself

12.3.4.3.1. not really a choice for a regular developer like me!

12.3.4.4. PyPy supports both Python 2 and 3

13. Python functions

13.1. Python function positional arguments

13.2. Python function keyword arguments

13.2.1. if you mix keyword and positional arguments when invoking a function, all positional arguments must precede keyword, otherwise an exception will raise

13.3. Python function invocation

13.4. Python print() function

13.4.1. takes multi type arguments

13.4.2. converts all output to string type

13.5. Python built-in functions

13.6. Python input() function

13.6.1. take user input

13.6.2. optional string argument for prompt

13.6.3. must assign to variable

13.6.4. type returned is always string

13.6.4.1. but you can cast by enclosing input() in a cast function such as int()

13.7. Python range() function

13.7.1. often used with for loops

13.7.2. takes 3 args, all integers: start, stop, step

13.7.2.1. only stop is mandatory

13.7.2.1.1. last value produced is stop -1

13.7.2.2. start defaults to 0

13.7.2.3. step defaults to 1

13.7.3. example

13.7.3.1. range(10)

13.7.3.1.1. produces integers 0 to 9

13.7.3.2. range(2,8)

13.7.3.2.1. produces: 2 to 7

13.7.3.3. range(3,9,2)

13.7.3.3.1. produces: 3,5,7

13.8. Python len() function

13.8.1. often used with lists

13.8.2. takes object as argument and returns number of elements in that object

13.9. Python user-defined functions

13.9.1. syntax

13.9.1.1. def name_of_function(<optional params>): <function body>

13.9.2. functions are invoked

13.9.2.1. definition must precede invocation

13.9.2.2. after function body is executed, interpreter returns to line after invocation

13.9.3. function names must be unique and must not clash with variable names

13.9.4. if you invoke a function and pass any argument that is not matched to a parameter in the function definition, this will generate an exception

13.9.5. parameters exist inside functions, arguments exist outside functions

13.9.5.1. parameter values are set at moment of function invocation

13.9.5.2. parameters can only be declared between the parentheses ( ) of function definition

13.9.5.3. arguments can be passed two ways

13.9.5.3.1. positional arguments

13.9.5.3.2. keyword argument passing

13.9.5.3.3. you can mix styles but positional args must precede keyword args

13.9.5.3.4. beware passing arg as both positional and keyword, as it throws exception

13.9.5.4. parameters can be defined with default values, which kick in if the associated argument is omitted during invocation

13.9.5.4.1. def myFunction(firstName, lastName = "Smith"): print("Hello", firstName, lastName)

13.9.5.4.2. beware that you must place all pre-defined parameters at end, as you will get an exception if you mix them with mandatory parameters

13.9.5.5. parameters can be mapped to any valid Python type, including lists

13.9.6. parameter names can be same as variable names that are declared outside function

13.9.6.1. invokes shadowing

13.9.6.1.1. parameter takes temporary control of variable, then previous assignment returns

13.9.7. functions can produce effects and produce results

13.9.7.1. return

13.9.7.1.1. keyword

13.9.7.1.2. causes immediate termination of function body

13.9.7.1.3. without expression

13.9.7.1.4. with expression

13.9.7.1.5. functions can return any valid Python data type

13.10. Python tuple() function

13.10.1. convert an iterable type like a list or string to a tuple

13.11. Python list() function

13.11.1. convert an iterable type like a tuple or string to a list

13.12. Python dict() function

13.12.1. covert an iterable type in the right "key-value" structure to a dictionary

13.12.1.1. example of "right" structure (a tuple of tuples in this case)

13.12.1.1.1. colors = (("green", "#008000"), ("blue", "#0000FF")) colDict = {} for t in colors: colDict.update(dict([t])) print(colDict)

13.12.2. dict() supports 3 ways to create dictionary objects via its parameters: 1) keyword arguments (known as kwargs), 2) mapping, 3) iterable

13.12.2.1. **kwargs

13.12.2.1.1. print(dict(m=8, n=9))

13.12.2.1.2. kwargs can combine with mapping or iterable

13.12.2.1.3. ** means an arbitrary number of kwargs

13.12.2.2. mapping

13.12.2.2.1. print(dict({"m":8, "n":9}))

13.12.2.3. iterable

13.12.2.3.1. print(dict([("m",9),("n",10)]))

13.12.2.4. all arguments optional

13.12.2.4.1. dict()

14. Python operators

14.1. Python exponentiation

14.1.1. if either base or exponent is float vs int, float trumps and result is given in float

14.1.1.1. same applies to multiplication

14.1.2. **

14.2. Python division

14.2.1. /

14.2.2. result is always float even if dividend and divisor are int and result is whole number

14.3. Python floor division

14.3.1. //

14.3.2. aka integer division

14.3.3. Integer divisional operator (//) with one float will produce float result but fractional part rounded down to zero

14.4. Python modulo division

14.4.1. %

14.5. Binary vs Unary operators

14.5.1. Binary operator requires two arguments, one to left, one to right

14.5.1.1. Example: 3+5

14.5.2. Unary operator requires one argument to right

14.5.2.1. Example: -3

14.6. Python operator precedence

14.6.1. Python operator binding

14.6.1.1. When precedence order of operators is same, left binding generally takes precedence

14.6.1.1.1. Example: 6 % 3 % 2 is same as (6 % 3) % 2

14.6.1.1.2. Exception is exponention operator (**)

14.7. Python comparison operators

14.7.1. equality

14.7.1.1. ==

14.7.1.2. can assess int as equal to float

14.7.1.2.1. e.g. 2 == 2.0 returns True

14.7.1.3. can assess int as equal to True/False

14.7.1.3.1. e.g. 1 == True returns True

14.7.1.3.2. e.g. 0 == True returns False

14.7.1.3.3. e.g. 0 == False returns True

14.7.1.3.4. True is equal to 1, False is equal to 0

14.7.2. inequality

14.7.2.1. !=

14.7.3. less/more than

14.7.3.1. >

14.7.3.2. >=

14.7.3.3. <

14.7.3.4. <=

14.7.4. Precedence is below + and i binary operators

14.7.4.1. less/more trumps equality/inequality

15. Python comments

15.1. #

16. Python string concatenation

16.1. string + string

17. Python conditional statements

17.1. indentation important

17.1.1. must be consistent

17.1.2. cannot mix tabs and spaces

17.2. Python if statement

17.2.1. if <Boolean expression>: <instruction(s)> elif <Boolean expression>: <instruction(s)> else: <instruction(s)>

17.2.2. when branch is single instruction, Python permits it to be on same line

17.2.2.1. example

17.2.2.1.1. if a > b: x = a else: x = b

17.3. if-elif-else is known as cascade

17.3.1. else branch must always be last in cascade

17.3.2. else is optional in cascade

18. Python logical operators

18.1. binary operators

18.1.1. and

18.1.1.1. logical conjunction

18.1.2. or

18.1.2.1. lower priority than and

18.1.2.2. logical disjunction

18.1.3. lower priority than comparison operators

18.2. unary operator

18.2.1. not

18.2.1.1. very high priority

18.2.1.1.1. equivalent to unary + and -

18.2.1.2. logical negation

18.3. De Morgan's laws

18.3.1. not (p and q) == (not p) or (not q) not (p or q) == (not p) and (not q)

18.4. any non 0 bit in whole evaluates to True

18.4.1. examples

18.4.1.1. print(bool(2 + 3))

18.4.1.1.1. returns True

18.4.1.2. print(bool(2 - 2))

18.4.1.2.1. returns False

18.4.1.3. print(not bool(2))

18.4.1.3.1. returns False

19. Python Collections

19.1. Python Lists

19.1.1. defined by elements inside square brackets [ ]

19.1.2. mutable (i.e. changeable)

19.1.3. assignment example

19.1.3.1. numbers = [1, 4, 8, 10, 19]

19.1.3.2. myList = []

19.1.3.2.1. creates an empty list

19.1.4. accessed by index

19.1.4.1. zero-based

19.1.4.2. example

19.1.4.2.1. print(numbers[0])

19.1.4.2.2. print(numbers[4])

19.1.4.3. negative indexes allowed

19.1.4.3.1. -1 means last in list, -2 second to last, etc

19.1.5. duplicate values allowed

19.1.6. remove elements with del instruction

19.1.6.1. example

19.1.6.1.1. del numbers[1]

19.1.6.2. del reduces length of list (i.e. len() function will return previous value minus 1)

19.1.6.3. del can also remove slices from a list

19.1.6.3.1. example

19.1.6.4. when using del with a variable pointed to a list but no reference to an element or slice, only pointer is deleted, not the underlying list

19.1.6.4.1. example

19.1.7. Python list object methods

19.1.7.1. list.append()

19.1.7.1.1. takes 1 arg

19.1.7.1.2. adds arg to end of list

19.1.7.1.3. increases length of list by 1

19.1.7.2. list.insert()

19.1.7.2.1. takes 2 args

19.1.7.2.2. shifts all list elements to right of insert index by 1

19.1.7.2.3. increases length of list by 1

19.1.7.3. list.sort()

19.1.7.3.1. takes 0 - 2 args (i.e. both args optional)

19.1.7.4. list.reverse()

19.1.7.4.1. no args

19.1.7.4.2. reverses element order in list

19.1.7.5. list.count()

19.1.7.5.1. counts number of occurrences of arg value in list

19.1.8. for loop can access all list elements without needing to specify length or use indexes

19.1.8.1. syntax: for i in aList: print(i)

19.1.8.1.1. prints element value without needing to access index

19.1.9. Lists can be nested (e.g. lists within lists within lists, etc.)

19.1.10. List elements can be of mixed types

19.1.11. Lists can be added together using the binary + operator

19.1.11.1. list1 = [1,2] list2 = [3,4] print(list1 + list2)

19.1.11.1.1. [1,2,3,4]

19.1.12. Lists can be multiplied using the * operator and an integer

19.1.12.1. list1 = [1,2] print(list1 * 3)

19.1.12.1.1. [1,2,1,2,1,2]

19.2. Complex data types are stored differently to simple scalar types

19.2.1. for ordinary variable assigned to scalar value think of it as the name of the content

19.2.2. for variables assigned to complex types like lists, think of it as a memory location where the data is stored

19.2.2.1. important implication by example

19.2.2.1.1. list1 = [1] list2 = list1 list1[0] = 2 print(list2)

19.2.2.2. Python slice

19.2.2.2.1. use this to make copy of types like list

19.2.2.2.2. syntax is [start:end]

19.2.2.2.3. you can also specify increment, which if omitted, defaults to 1

19.3. Python membership operators

19.3.1. in

19.3.2. not in

19.3.3. return True or False when element found/not found in sequence

19.3.4. example

19.3.4.1. list1 = ["Hello","World"] print("Hello" in list1) print("Hello" not in list1)

19.3.4.1.1. returns: True False

19.4. Python list comprehension

19.4.1. Provides a concise way to create lists

19.4.2. syntax

19.4.2.1. [expression for element in list if conditional]

19.4.2.1.1. equivalent to

19.4.2.1.2. if conditional is optional

19.4.2.1.3. expression resolves to something that is added to list via the for loop

19.4.3. examples

19.4.3.1. x = "hello world" y = [x for i in range(4)] print(y)

19.4.3.1.1. returns

19.4.3.1.2. x is data used to fill list

19.4.3.1.3. clause specifying how many times to repeat x in list is: for i in range(4)

19.4.3.2. wordList = ["hello","world","how","are","you"] myWords = [w for w in wordList if w[0] == "h"] #all words beginning with 'h' print(myWords)

19.4.3.2.1. returns

19.4.3.2.2. w represents the iterating element in the list (wordList) and the data being picked to fill the new list (myWords)

19.4.3.2.3. if statement enables a conditional filter to determine which instances of w get added to new list

19.4.4. 2D arrays

19.4.4.1. aka matrix

19.4.4.2. think "table"

19.4.4.3. example

19.4.4.3.1. e = 0 myArray = [[e for i in range(3)] for i in range(3)] print(myArray)

19.5. Python sequence unpacking

19.5.1. syntactic sugar for exploding lists and tuples into multiple variable assignments in one line of code

19.5.1.1. list example

19.5.1.1.1. myList = [1, 2, 3] a, b, c = myList print(a) print(b) print(c)

19.5.1.2. tuple example

19.5.1.2.1. myTuple = (4, 5, 6) a, b, c = myTuple print(a) print(b) print(c)

19.5.1.3. but if you specify more than one variable on left side but that number does not correspond to number of sequence elements, this will raise exception

19.5.1.3.1. myTuple = (4, 5, 6) a, b = myTuple print(a) print(b) print(c)

19.6. Python Tuples

19.6.1. A tuple is an immutable sequence type

19.6.2. syntax to create them uses parentheses ( ) rather than the brackets [ ] used for lists

19.6.2.1. example

19.6.2.1.1. tuple1 = (1, 2, 4, 8) tuple2 = 1., .5, .25, .125

19.6.2.2. you can also create a tuple with just a comma separated element assignment

19.6.2.3. empty tuple assignment allowed, requires empty parentheses ( )

19.6.2.3.1. emptyTuple = ()

19.6.2.4. To create a 1-element tuple, you must put a comma after the element value, otherwise (if you omit comma) the variable will be assigned a single value type, not a tuple

19.6.2.4.1. oneElementTuple1 = (1, ) oneElementTuple2 = 1.,

19.6.3. elements can be mix of any data type, including complex types

19.6.4. For read operations, all the same methods used for lists work the same with tuples

19.6.5. Any attempt to use a list write operation on a tuple will raise an exception

19.6.5.1. myTuple = 1, 2, 3 del myTuple[2] #throws exception myTuple[2] = 4 #throws exception

19.6.5.2. myList = [1, 2, 3] myList.append(4) print(myList) myTuple = (1, 2, 3) myTuple.append(4) #throws exception print(myTuple)

19.6.5.3. but tuples can be deleted as a whole

19.6.5.3.1. del myTuple

19.6.6. You can use the binary + and * operators with tuples and the behaviour is the same as for lists

19.6.6.1. myTuple = 1, 2, 3 myTuple += 4, print(myTuple)

19.6.6.1.1. returns

19.6.6.1.2. note: the += "addition to self" combines two tuples into a new tuple and re-assigns variable to that

19.6.7. You can use the in and not operators with tuples and the behaviour is the same as for lists

19.7. Python Dictionaries

19.7.1. A dictionary is mutable but not a sequence type

19.7.1.1. In Python 3.6x dictionaries have become ordered collections by default.

19.7.2. Elements are key-value pairs

19.7.2.1. key and value are separated by colon

19.7.2.2. key-value pairs are separated by commas

19.7.3. Every key must be unique

19.7.4. Keys can be numbers (int or float) or strings

19.7.5. syntax for assignment uses curly braces { }

19.7.5.1. myE2IDictionary = { "hi" : "ciao", "today" : "oggi", "kiss" : "bacio" }

19.7.6. When keys are string type, they are case-sensitive

19.7.7. Values are retrieved by using keys in same style as list and tuple elements are retrieved via indexes [ key ]

19.7.7.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} print(dict["dog"])

19.7.7.1.1. returns

19.7.7.2. you can also use dictionary get() method

19.7.7.2.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} print(dict.get("dog"))

19.7.8. Key must exist, else exception is thrown

19.7.8.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} print(dict["Dog"])

19.7.8.1.1. throws exception

19.7.8.2. avoid this exception using in or not in operations

19.7.8.2.1. if "horse" in dict: print(dict["horse"]) else: print("horse not in dictionary")

19.7.9. dictionaries can be iterated using for loops, and there are various dictionary methods that can be useful

19.7.9.1. keys()

19.7.9.1.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} for key in dict.keys(): print(key,"->",dict[key])

19.7.9.2. sorted()

19.7.9.2.1. to get a sorted key list, you can use the built in sorted() function

19.7.9.3. items()

19.7.9.3.1. you can also iterate using the items() method, which returns all the key-value pairs as a list of tuples

19.7.9.4. values()

19.7.9.4.1. you can also iterate using the values() method, which returns all the values as a list

19.7.9.5. you can also iterate a dictionary without using any of these methods, as a for loop will naturally iterate all the keys

19.7.9.5.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} for key in dict: print(key,"->",dict[key])

19.7.9.6. when for loop specifies two or more dictionaries to iterate, the loop variable references the whole dictionary rather than the keys

19.7.9.6.1. for example, this code combines two dictionaries together in a third one (d3)

19.7.10. modifying dictionaries

19.7.10.1. update values

19.7.10.1.1. dict['cat'] = "miccio"

19.7.10.1.2. dict.update({'dog' : 'canelino'})

19.7.10.2. add key-value pairs

19.7.10.2.1. dict['snake'] = 'serpente'

19.7.10.2.2. dict.update({'cow' : 'mucca'})

19.7.10.3. delete key-value pairs

19.7.10.3.1. del dict["snake"]

19.7.10.3.2. dict.popitem()

19.7.10.3.3. del dict

19.7.10.3.4. dict.clear()

19.7.11. copying dictionaries with the copy() method

19.7.11.1. copyDict = dict.copy()

20. Python modules

21. Python global keyword and variable scope

21.1. when preceding variable name in a function (or other structure with local scope), enables function to change value of variable that persists outside function body

21.2. for multiple variables, separate each by comma after global password

21.3. example

21.3.1. def myFunction(): global x x = 4 print("x is set inside function") x = 3 myFunction() print(x)

21.3.1.1. returns

21.3.1.1.1. x is set inside function 4

21.4. as general rule, variable declared and assigned in main program has scope inside function body, but variables declared and set inside functions have local scope only

21.4.1. assigning new value to external variable will only affect value inside function unless you previously declare variable inside function body using global keyword

21.4.1.1. del with lists is exception

21.4.1.1.1. x = [5,10] def myFunction(y): print("inside, x =",x) del x[0] print("inside, x =",x) myFunction(x) print("outside, x =",x)

21.4.2. don't try to read external variable and then set it, as you will get exception (local variable referenced before assignment), but global declaration can fix that

21.4.2.1. bad example (throws exception)

21.4.2.1.1. x = 5 def myFunction(y): a = x x = y + 1 print("inside, x =",x) myFunction(x) print("outside, x =",x)

21.4.2.2. good example (no exception)

21.4.2.2.1. x = 5 def myFunction(y): global x a = x x = y + 1 print("inside, x =",x) myFunction(x) print("outside, x =",x)

21.5. you can declare variable inside function with same name as a variable declared outside function, but in this case local variable is treated as separate with local scope only

22. Python function recursion

22.1. Function that invokes itself

22.1.1. example

22.1.1.1. def fib(n): if n < 1: return None if n < 3: return 1 return fib(n - 1) + fib(n - 2) for n in range(1, 10): print(n, "->", fib(n))

22.1.2. recursive invocation should involve reducing the problem towards a base case that solves the problem

22.1.2.1. adding print helps clarify

22.1.2.1.1. failure example (endless loop)

22.1.2.1.2. success example (base case)

22.1.2.2. you will need an if statement to ensure base case is satisfied and recursion ends

22.2. Beware that recursive function calls can consume a lot of memory and care must be taken to avoid endless loop conditions

23. Python mutable and immutable data types

23.1. mutable types allow element values to be changed after initial variable assignment, via index reference - immutable types do not

23.2. immutable types

23.2.1. in-built types like int, float, bool, string, unicode, tuple

23.2.1.1. example

23.2.1.1.1. myString = "Hello" myString[1] = "a"

23.3. mutable types

23.3.1. list, dict, set

23.4. Immutable objects are quicker to access and are expensive to change because it involves the creation of a copy. Whereas mutable objects are easy to change.