Why use type hints in python? Python being a dynamically typed language means that variable types are determined during run time. However, declaring the expected type can be beneficial in very large projects as the code becomes self-documenting and make it more readable. FAANG also expect their python developers to know how to use type hints in code. Google has a Python style guide that can be found here.
Initializing Lists
Lists are a built-in data type in Python used to store multiple items in a single variable and are initialized in two ways :
- Using square brackets :
from typing import List, Any
my_empty_list: List[Any] = []
print(my_empty_list)
my_list_of_integers: List[int] = [1,2,3,4]
print(my_list_of_integers)
my_list_of_floats: List[float] = [1.2, 3.4, 5.6]
print(my_list_of_floats)
my_list_of_strings: List[str] =["this", "is" ,"a" ,"string"]
print(my_list_of_strings)
my_list_of_booleans: List[bool] =[True,False,False,True]
print(my_list_of_booleans)
my_mixed_list: List[Any] = [1, "Hello", False, 1.23]
print(my_mixed_list)
Output:
[]
[1, 2, 3, 4]
[1.2, 3.4, 5.6]
['this', 'is', 'a', 'string']
[True, False, False, True]
[1, 'Hello', False, 1.23]
- Using the list constructor :
from typing import List, Any
my_empty_list: List[Any] = list()
print(my_empty_list)
my_list_of_integers: List[int] = list((1,2,3,4))
print(my_list_of_integers)
my_list_of_floats: List[float] =list ((1.2, 3.4, 5.6))
print(my_list_of_floats)
my_list_of_strings: List[str]=list (("this", "is" ,"a" ,"string"))
print(my_list_of_strings)
my_list_of_booleans: List[bool] =list((True, False,False,True))
print(my_list_of_booleans)
my_mixed_list: List[Any]= list((1, "Hello", False, 1.23))
print(my_mixed_list)
Output:
[]
[1, 2, 3, 4]
[1.2, 3.4, 5.6]
['this', 'is', 'a', 'string']
[True, False, False, True]
[1, 'Hello', False, 1.23]
Characteristics of list items
Items in a list have the following characteristics :
- Order
The list items are said to be ordered when they follow each other in a set manner. By default, new items are added to the very end of the list
- Can hold duplicates
Since the list has an order and every item in the list has a unique index, we can duplicate values within the list as much as we want.
For example ```py my_list = [1,2,2,5,6,3,4]
The two 2's are in different positions yet have the same value.
3. Can be changed
We can add, remove and change elements in a list.
## Accessing items in a list
### Positive indexing
> Positive indexing means we start from the beginning of the list
Every item in the list has a unique index. Index values begin at zero, meaning that the first element in a list is in index zero. We use square brackets containing the index of the list we want.
For example,
Given the list:
```py
# list of only integers
my_list: List[int] = [1,2,2,5,6,3,4]
We can access the first element in the list (1) using :
my_list: List[int] = [1,2,2,5,6,3,4]
first_item: int= my_list[0]
print(first_item)
The general access expression is :
list_item_you_want: List[type of list items the list will contain] = the_list[list_item_index]
Negative indexing
Negative indexing means we start from the end of the list.
We can also access the list items from the last element using negative indexing.
For example,
Given the list :
adele_lyrics: List[str] = ["Hello", "from" ,"the" ,"other", "side"]
To get the last element, we can use negative indexing : ```py
List of only strings
adele_lyrics: List[str] = ["Hello", "from" ,"the" ,"other", "side"]
The last element of the string which is of type str(string)
last_word: str = adele_lyrics[-1]
print(last_word) Output :sh side To get the second last element :py
List of only strings
adele_lyrics: List[str] = ["Hello", "from" ,"the" ,"other", "side"]
The second last element of the string which is of type str(string)
second_last_word: str = adele_lyrics[-2]
print(second_last_word) Output :sh other ```

Range of indexes
A range of indexes helps get a sublist from the list.
For example:
Given the list :
fruits: List[str] = ["oranges", "grapefruits","mandarins ","limes","strawberries","raspberries","blueberries","watermelons","rockmelons ","passionfruit","banana",]
From the list of the fruits we can tell that we have at least three categories of fruits on the list :
Citrus fruits -> oranges to limes
Berries -> strawberries to blueberries
Melons -> watermelons to rockmelons
Using range indexing we can get the three categories. The range indexing general expression is :
sublist = the_list[start_index: end_index]
Note that the end_index is not inclusive. For example, a start index of 2 and an end index of 5 will only return elements from the second index to the fourth index.
To get the :
citrus_fruits: List[str] = fruits[0:4]
print(citrus_fruits)
Output:
['oranges', 'grapefruits', 'mandarins ', 'limes']
berries_fruits: List[str] = fruits[4:7]
print(berries_fruits)
Output: ['strawberries', 'raspberries', 'blueberries']
melon_fruits: List[str] = fruits[7:9]
print(melon_fruits)
Output:
['watermelons', 'rockmelons ']
We can also use negative indexing to get the melons.
To include rockmelons in the sublist we can index from watermelons to the passionfruit index which can either be 9 or -2
melon_fruits: List[str] = fruits[7:-2]
print(melon_fruits)
Output:
['watermelons', 'rockmelons ']
Length of a list
There are instances when we may need to know how many items are present in a list.
Python has an inbuilt function for this :
numbers_list: List[int] = [0,1,2,3,4,5,6,7,8,9,10]
number_of_list_items: int = len(numbers_list)
print(number_of_list_items)
Output:
11
Example use case:
Given a list get all the values in a list that are in an even index.
def get_all_values_in_even_indexes(the_list: List[Any]) -> List[Any]:
""" Get all values that are in even indexes in a list
Args:
the_list: List of values.
Returns:
List of all values in even indexes
"""
even_list: List[Any] = []
for index in range(len(the_list)):
if index % 2 == 0:
even_list.append(the_list[index])
print(even_list)
return even_list
items_in_even_indexes = get_all_values_in_even_indexes(["Zero","One", "Two", "Three", "Four", "Five", "Six"])
Output
['Zero', 'Two', 'Four', 'Six']
List manipulations
Changing values in a list
To replace the value of a list item, we can refer to its index number and change the value.
Going back to the fruits example, to change limes to lemons we simply do:
fruits: List[str] = ["oranges", "grapefruits", "mandarins ", "limes", "strawberries", "raspberries", "blueberries",
"watermelons", "rockmelons ", "passionfruit", "banana"]
fruits[3]: str = 'lemons'
Output:
['oranges', 'grapefruits', 'mandarins ', 'lemons', 'strawberries', 'raspberries', 'blueberries', 'watermelons', 'rockmelons ', 'passionfruit', 'banana']
Using range indexing we can also change the values on a list. On the fruits list, we can change the berries to leafy greens as follows:
leafy_greens: List[str]= ["lettuce","spinach","silverbeet"]
fruits[4:7] = leafy_greens
print(fruits)
Output: sh ['oranges', 'grapefruits', 'mandarins ', 'lemons', 'lettuce', 'spinach', 'silverbeet', 'watermelons', 'rockmelons ', 'passionfruit', 'banana']
Adding items in a list
We can also insert items in an index without replacing the existing values. In the fruits example, we can add a new citrus fruit after lemons without replacing lettuce.
fruits.insert(4,"pomelo")
print(fruits)
Output :
['oranges', 'grapefruits', 'mandarins ', 'lemons', 'pomelo', 'lettuce', 'spinach', 'silverbeet', 'watermelons', 'rockmelons ', 'passionfruit', 'banana']
To add items at the end of a list we use the append() method: