Functions
At the most basic level, you can think of functions as a set of instructions that take an input and return and outputs.
For example, the primary task of the print function is to print a value. This value is usually printed to the screen and it’s passed to the print function as argument.
Function
A Python function is a modular piece of code that can be re-used repeatedly. A function is declared using the
def
keyword followed by the name and task to complete.
Optional parameters can also be added after the function name within a pair of parentheses.
Examples
Calculate a tax amount for a customer, based on the total value of that bill.
WARNING
A function is only ever run when it’s actually being called.
TIP
One of the nice things about a function is that you can update it once and any part of the code that calls that function will get those changes as well.
Variable scope
Variables within the built-in and global scope are accessible from anywhere in the code.
The purpose of scope is to protect the variable, so it does not get changed by other parts of the code.
NOTE
As a rule, global scope is generally discouraged in applications as this increases the possibility of mistakes in outputs.
Global scope
That’s because it’s only accessible from within the local scope of the function fn1.
Built-in scope refers to what’s called the reserved keywords, such as print and def. Built-in scope covers all the language of Python, which means you can access it from the outermost scopes or the innermost scopes in the function classes.
Function and variable scope
Functions and variables
It is essential to understand the levels of scope in Python and how things can be accessed from the four different scope levels. Below are the four scope levels and a brief explanation of where and how they are used.
1. Local scope
Local scope refers to a variable declared inside a function. For example, in the code below, the variable total
is only available to the code within the get_total
function. Anything outside of this function will not have access to it.
2. Enclosing scope
Enclosing scope refers to a function inside another function or what is commonly called a nested function.
In the code below, I added a nested function called double_it
to the get_total
function.
As double_it
is inside the scope for the get_total
function it can then access the variable. However, the enclosed variable inside the double_it
function cannot be accessed from inside the get_total
function.
3. Global scope
Global scope is when a variable is declared outside of a function. This means it can be accessed from anywhere.
In the code below, I added a global variable called special
. This can then be accessed from both functions get_total
and double_it
:
4. Built-in scope
Built-in scope refers to the reserved keywords that Python uses for its built-in functions, such as print, def, for, in
, and so forth. Functions with built-in scope can be accessed at any level.
What are data structures?
This reading introduces you to data structures. So far, you have only stored small bits of data in a variable. This was either an integer, Boolean or a string.
But what happens if you need to work with more complex information, such as a collection of data like a list of people or a list of companies?
Data structures are designed for this very purpose.
A data structure allows you to organize and arrange your data to perform operations on them. Python has the following built-in data structures: List, dictionary, tuple and set. These are all considered non-primitive data structures, meaning they are classed as objects, this will be explored later in the course.
Along with the built-in data structures, Python allows users to create their own. Data structures such as Stacks, Queues and Trees can all be created by the user.
Each data structure can be designed to solve a particular problem or optimize a current solution to make it much more performant.
Mutability and Immutability
Data Structures can be mutable or immutable. The next question you may ask is, what is mutability? Mutability refers to data inside the data structure that can be modified. For example, you can either change, update, or delete the data when needed. A list is an example of a mutable data structure. The opposite of mutable is immutable. An immutable data structure will not allow modification once the data has been set. The tuple is an example of an immutable data structure.
Lists
List
Lists are a sequence of one or more different or similar datatypes. A list in Python is essentially a dynamic array that can hold any datatype.
Examples
The type doesn’t necessarily matter. It’s just going to be stored in the same way.
One thing to keep in mind with lists is that they are based on an index.
Nested list
That’s completely valid as well. Any datatype can be stored within the list itself, just to keep that in mind.
Print the whole list
Adding items to the list
Instead of having to specify the index or where the items should be placed, I can just put it in the append keyword.
There is another function I can use if I wanted to add one or more items to the list.
Removing item from list
Iteration through lists
Tuples
A tuple can accept any mix of data types.
TIP
Even if you don’t use parenthesis, it still is indicated as tuple.
That’s because anything that is declared in a tuple is immutable.
Sets
Sets differ slightly from lists, in that they don’t allow duplicate values.
NOTE
An additional important thing about sets is that a set is a collection with no duplicates but it’s also a collection of unaltered items. Unlike a list where I can print out content based on index.
Dictionaries
In a normal dictionary, to locate a word, you look it up by the first letter and then use the alphabetical ordering system to find its location. Likewise, Python dictionaries are optimized to retrieve values.
Dictionaries access values based on keys and not on index position. Therefore, they are faster and more flexible in operation.
With a Python dictionary, a key is assigned to a specific value. This is called the key-value pair. The benefits of this method is that it’s much faster than using traditional lists.
To find an item in a list, you need to keep reviewing the list until you locate the item. But in a Python dictionary, you can go straight to the item you need by using its key.
A dictionary is also immutable in that the values can be changed or updated.
Access
Update
Delete
Iteration
Three different methods to iterate over the dictionary:
- standard iteration method,
- the items function
- or the values function
TIP
The key can be numeric, it can be string.
kwargs
Using these has the advantage that you could pass in any amounts of non-keyword variables, and keyword arguments.
TIP
args
here is a tuple. The name can be different too.
WARNING
There is two stars before
kwargs
!
TIP
The type of the
kwargs
here is dictionary. The name can be different too.
Choosing and using data structures
This reading illustrates the importance of chosing the correct data structure for the task at hand.
Which data structure to choose?
The tricky part for new developers is understanding which data structure is suited to the required solution. Each data structure offers a different approach to storing, accessing and updating the information stored inside it. There can be many factors to select from, including size, speed and performance. The best way to try and understand which one is more suitable is through an example.
Example: Employees list
In this example, there’s a list of employees that work in a restaurant. You need to be able to find an employee by their employee ID - an integer-based numeric ID. The function get_employee
contains a for
loop to iterate over the list of employees and returns an employee object if the ID matches.
In this code, employee_list
is a list of tuples. The code runs well and will return the user Paul, as its ID, 12458, is matched. The challenge comes when the list gets bigger.
Instead of two employees, you may have 2000 or even 20,000. The code will have to iterate over the list sequentially until the number is matched.
You could optimize the code to split the search, but even with this, it still lacks in performance in comparison to other data structures, such as the dictionary.
Notice how, in this code block, if you change the data structure to use a dictionary, it will allow you to find the employee. The main difference is that you no longer need to iterate over the list to locate them. If the list expands to a much larger size, the seek time to find the employee stays the same.
This is a prime example of how to choose the right data structure to suit the solution.
Both work well, but the trade-off to be considered is that of time and scale. The first solution will work well for smaller amounts of data, but loses performance as the data scales.
The second solution is better suited to large amounts of data as its structure allows for a constant seek time allowing large amounts of data to be accessed at a constant rate.
This example shows that there is no one size fits all solution and careful consideration should be given to the choice of data structure to be used depending on the constraints of the solution.
Additional resources
Here is a list of resources that may be helpful as you continue your learning journey.
Learn more about Python data structures (Python documentation) on the Python website: Python.org - Data structuresÂ
Explore common Python data structures at the Real Python website: Real Python - Data structures
FunctionDate-StructurePythonscope
Previous one → 2.Control flow and conditionals | Next one → 4.Errors, Exceptions and File handling