Python Tutorial #3: Lists and Data Structure Methods
Lists in Python are one of the most versatile and widely used data structures. In this article, we will explore in detail the methods that make lists such a powerful tool, and see how they can be used in different scenarios.
Lists
Lists in Python are one of the most versatile and widely used data structures. They are mutable sequences that can contain elements of different types, including other lists. Lists are defined using square brackets [] and elements are separated by commas.
mi_lista = [1, 2, 3, "python", [4, 5, 6]]
Main Methods of Lists
Lists in Python come equipped with a variety of useful methods. Let’s look at the most important ones:
-
append(x): Adds an element to the end of the list.
frutas = ['manzana', 'banana'] frutas.append('naranja') print(frutas) # Salida: ['manzana', 'banana', 'naranja'] -
extend(iterable): Adds all elements of an iterable to the end of the list.
numeros = [1, 2, 3] numeros.extend([4, 5]) print(numeros) # Salida: [1, 2, 3, 4, 5] -
insert(i, x): Inserts an element at a specific position.
letras = ['a', 'c', 'd'] letras.insert(1, 'b') print(letras) # Salida: ['a', 'b', 'c', 'd'] -
remove(x): Removes the first element with the specified value.
colores = ['rojo', 'verde', 'azul', 'verde'] colores.remove('verde') print(colores) # Salida: ['rojo', 'azul', 'verde'] -
pop([i]): Removes and returns the element at the given position (or the last one if not specified).
stack = [3, 4, 5] elemento = stack.pop() print(elemento) # Salida: 5 print(stack) # Salida: [3, 4] -
clear(): Removes all elements from the list.
mi_lista = [1, 2, 3] mi_lista.clear() print(mi_lista) # Salida: [] -
index(x[, start[, end]]): Returns the index of the first element with the specified value.
animales = ['gato', 'perro', 'conejo', 'perro'] indice = animales.index('perro') print(indice) # Salida: 1 -
count(x): Counts how many times an item appears in the list.
numeros = [1, 2, 2, 3, 2, 4] conteo = numeros.count(2) print(conteo) # Salida: 3 -
sort(): Sorts the list in place.
desordenada = [3, 1, 4, 1, 5, 9, 2] desordenada.sort() print(desordenada) # Salida: [1, 1, 2, 3, 4, 5, 9] -
reverse(): Reverses the order of the elements in place.
mi_lista = [1, 2, 3, 4] mi_lista.reverse() print(mi_lista) # Salida: [4, 3, 2, 1] -
copy(): Creates a shallow copy of the list.
original = [1, [2, 3], 4] copia = original.copy() copia[1][0] = 'a' print(original) # Salida: [1, ['a', 3], 4] print(copia) # Salida: [1, ['a', 3], 4]
Practical Examples
Let’s look at some examples to illustrate how these methods are used:
# Creamos una lista de frutas
frutas = ['naranja', 'manzana', 'pera', 'plátano', 'kiwi', 'manzana', 'plátano']
# Contamos cuántas manzanas hay
print(frutas.count('manzana')) # Salida: 2
# Encontramos el índice del primer 'plátano'
print(frutas.index('plátano')) # Salida: 3
# Invertimos el orden de la lista
frutas.reverse()
print(frutas) # Salida: ['plátano', 'manzana', 'kiwi', 'plátano', 'pera', 'manzana', 'naranja']
# Agregamos una nueva fruta
frutas.append('uva')
print(frutas) # Salida: [..., 'naranja', 'uva']
# Ordenamos la lista
frutas.sort()
print(frutas) # Salida: ['kiwi', 'manzana', 'manzana', 'naranja', 'pera', 'plátano', 'plátano', 'uva']
# Eliminamos y retornamos el último elemento
ultima_fruta = frutas.pop()
print(ultima_fruta) # Salida: 'uva'
print(frutas) # La lista ya no contiene 'uva'
Use as Specialized Structures
Lists in Python are so versatile that they can be used to implement other more specialized data structures:
Lists like Stacks and Queues
A stack follows the “last in, first out” (LIFO) principle. We can easily implement a stack with a list:
pila = [3, 4, 5]
pila.append(6) # Añadimos un elemento a la pila
pila.append(7)
print(pila) # Salida: [3, 4, 5, 6, 7]
elemento = pila.pop() # Removemos el último elemento
print(elemento) # Salida: 7
print(pila) # Salida: [3, 4, 5, 6]
Although lists can be used as queues (“first in, first out” principle or FIFO), they are not efficient for this purpose. For a more efficient implementation of queues, it is recommended to use collections.deque:
from collections import deque
cola = deque(["Eric", "John", "Michael"])
cola.append("Terry") # Terry llega
cola.append("Graham") # Graham llega
primer_cliente = cola.popleft() # El primero en llegar ahora se va
print(primer_cliente) # Salida: 'Eric'
print(cola) # Salida: deque(['John', 'Michael', 'Terry', 'Graham'])
List Comprehensions
List comprehensions are a powerful and elegant feature of Python that allows us to create new lists in a concise way. They are especially useful when we want to apply an operation to each element in a sequence or create a subsequence of elements that meet certain conditions.
Syntax and Examples
The basic syntax of a list comprehension is:
[expresion for elemento in iterable if condicion]
Where:
-
expresionis the operation that is applied to each element. -
elementois the variable that represents each item of the iterable. -
iterableis the sequence we are iterating over. -
if condicionis optional and is used to filter items.
- Create a list of squares:
cuadrados = [x**2 for x in range(10)]
print(cuadrados) # Salida: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
- Filter even numbers from a list:
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pares = [x for x in numeros if x % 2 == 0]
print(pares) # Salida: [2, 4, 6, 8, 10]
- Apply a function to each element:
frutas = [' banana', ' mora ', 'fresa ']
frutas_limpias = [fruta.strip() for fruta in frutas]
print(frutas_limpias) # Salida: ['banana', 'mora', 'fresa']
- Create a list of tuples:
coordenadas = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
print(coordenadas) # Salida: [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Nested Understandings
List comprehensions can be nested, allowing us to work with more complex data structures such as arrays.
# Ejemplo: Transponer una matriz
matriz = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
transpuesta = [[fila[i] for fila in matriz] for i in range(4)]
print(transpuesta)
# Salida: [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
This example creates a new matrix where the rows of the original matrix are converted to columns.
Matriz original: Matriz transpuesta:
┌─────────────┐ ┌───────────┐
│ 1 2 3 4 │ │ 1 5 9 │
│ 5 6 7 8 │ => │ 2 6 10 │
│ 9 10 11 12 │ │ 3 7 11 │
└─────────────┘ │ 4 8 12 │
└───────────┘
Proceso de transposición:
[1, 2, 3, 4] [1]
[5, 6, 7, 8] => [5] => [1, 5, 9]
[9, 10, 11, 12] [9]
[2]
[6] => [2, 6, 10]
[10]
[3]
[7] => [3, 7, 11]
[11]
[4]
[8] => [4, 8, 12]
[12]
Performance Considerations
Although list comprehensions are elegant and concise, it is important to use them sparingly. For very complex operations or when working with large data sets, a traditional loop may be more readable and efficient.
Additionally, for more complex tasks, Python offers the zip() function that can be very useful:
transpuesta = list(zip(*matriz))
print(transpuesta)
# Salida: [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
List comprehensions are a powerful tool in any Python programmer’s arsenal. They allow you to write cleaner and more expressive code, especially when it comes to transforming or filtering data. However, as with any powerful tool, it is important to use them judiciously to maintain code readability and efficiency.
The del instruction
The del instruction in Python is a versatile tool that can be used to remove elements from lists or even entire variables. Let’s see how it works:
-
Delete items from a list
a = [-1, 1, 66.25, 333, 333, 1234.5] del a[0] # Elimina el primer elemento print(a) # Salida: [1, 66.25, 333, 333, 1234.5] del a[2:4] # Elimina los elementos del índice 2 al 3 print(a) # Salida: [1, 66.25, 1234.5] del a[:] # Elimina todos los elementos de la lista print(a) # Salida: [] -
Delete variables
x = 10 del x # print(x) # This would raise an error because x no longer exists
The del instruction is useful when you need to remove specific list elements or free memory by deleting variables you no longer need.
Tuples
Tuples are another type of sequence in Python, similar to lists, but with one crucial difference: they are immutable. This means that once a tuple is created, we cannot change its elements.
Creation and unpacking
t = 12345, 54321, 'hello!'
print(t) # Salida: (12345, 54321, 'hello!')
# Tuplas anidadas
u = t, (1, 2, 3, 4, 5)
print(u) # Salida: ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
# Tupla de un solo elemento
singleton = 'hello',
print(singleton) # Salida: ('hello',)
Unpacking Tuples A useful feature of tuples is that they can be unpacked into individual variables:
x, y, z = t
print(x) # Salida: 12345
print(y) # Salida: 54321
print(z) # Salida: 'hello!'
Tuples are useful when we want to ensure that a collection of elements does not change, such as the coordinates of a point in space.
Sets
Sets in Python are unordered collections of single elements. They are useful for removing duplicates and performing set math operations.
Creation and Operations
# Usando llaves
frutas = {'manzana', 'naranja', 'manzana', 'pera', 'naranja', 'banana'}
print(frutas) # Salida: {'naranja', 'manzana', 'pera', 'banana'}
# Usando la función set()
a = set('abracadabra')
print(a) # Salida: {'a', 'r', 'b', 'c', 'd'}
Operations with sets
a = set('abracadabra')
b = set('alacazam')
print(a - b) # Diferencia: letras en a pero no en b
print(a | b) # Unión: letras en a o b o ambos
print(a & b) # Intersección: letras en ambos a y b
print(a ^ b) # Diferencia simétrica: letras en a o b pero no en ambos
Understanding sets
As with lists, we can use comprehensions to create sets concisely:
a = {x for x in 'abracadabra' if x not in 'abc'}
print(a) # Salida: {'r', 'd'}
Sets are extremely useful when we need to ensure that a collection does not have duplicate elements or when we need to perform set math operations efficiently.
These data structures (lists, tuples, and sets) are fundamental in Python and each has its own uses and advantages. Understanding when to use each is key to writing efficient and elegant Python code.
Dictionaries
Dictionaries are an extremely useful data structure in Python. Unlike sequences, which are indexed by a numerical range, dictionaries are indexed by keys, which can be any immutable type.
Creation, Use and Construction
# Creación de un diccionario
tel = {'jack': 4098, 'sape': 4139}
# Añadir un nuevo par clave-valor
tel['guido'] = 4127
print(tel) # Salida: {'jack': 4098, 'sape': 4139, 'guido': 4127}
# Acceder a un valor
print(tel['jack']) # Salida: 4098
# Eliminar un par clave-valor
del tel['sape']
# Añadir otro par clave-valor
tel['irv'] = 4127
print(tel) # Salida: {'jack': 4098, 'guido': 4127, 'irv': 4127}
# Obtener una lista de claves
print(list(tel)) # Salida: ['jack', 'guido', 'irv']
# Obtener una lista ordenada de claves
print(sorted(tel)) # Salida: ['guido', 'irv', 'jack']
# Comprobar si una clave existe
print('guido' in tel) # Salida: True
print('jack' not in tel) # Salida: False
- Construction There are several ways to build dictionaries:
# Usando el constructor dict()
dict1 = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
# Usando comprensión de diccionarios
dict2 = {x: x**2 for x in (2, 4, 6)}
# Usando argumentos de palabra clave cuando las claves son strings
dict3 = dict(sape=4139, guido=4127, jack=4098)
print(dict1) # Salida: {'sape': 4139, 'guido': 4127, 'jack': 4098}
print(dict2) # Salida: {2: 4, 4: 16, 6: 36}
print(dict3) # Salida: {'sape': 4139, 'guido': 4127, 'jack': 4098}
Iteration Techniques
Python offers several powerful techniques for iterating over data structures.
About Different Structures
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
print(k, v)
# Salida:
# gallahad the pure
# robin the brave
- Sequence enumeration
for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v)
# Salida:
# 0 tic
# 1 tac
# 2 toe
- Iteration over multiple sequences
questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
print(f'What is your {q}? It is {a}.')
# Salida:
# What is your name? It is lancelot.
# What is your quest? It is the holy grail.
# What is your favorite color? It is blue.
- Iteration in reverse order
Python allows you to iterate over sequences in reverse order using the
reversed()function:
for i in reversed(range(1, 10, 2)):
print(i)
# Salida:
# 9
# 7
# 5
# 3
# 1
- Iteration over an ordered sequence
To iterate over a sequence in order, we can use the
sorted()function:
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
for fruit in sorted(set(basket)):
print(fruit)
# Salida:
# apple
# banana
# orange
# pear
Note the use of set() to remove duplicates before sorting.
Safe Modification during Iteration
Sometimes we need to modify a list while we are looping through it. A safe way to do this is to create a new list:
import math
raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
filtered_data = [value for value in raw_data if not math.isnan(value)]
print(filtered_data) # Salida: [56.2, 51.7, 55.3, 52.5, 47.8]
Conditions in Python
Conditions in Python are very flexible and can include various types of operators and expressions.
Comparison and Boolean Operators
In addition to the standard comparison operators (<, >, ==, !=, <=, >=), Python offers:
inandnot in: to verify membershipisandis not: to compare object identity
a = [1, 2, 3]
b = [1, 2, 3]
print(2 in a) # Salida: True
print(4 not in a) # Salida: True
print(a is b) # Salida: False (son objetos diferentes)
print(a == b) # Salida: True (tienen el mismo contenido)
Chaining and Short Circuit Evaluation
- Comparisons can be chained intuitively:
a = 5
print(1 < a < 10) # Salida: True
- Boolean operators
Python uses the keywords
and,or, andnotfor Boolean operations:
x = 5
y = 10
z = 15
print(x < y and y < z) # Salida: True
print(x < y or y > z) # Salida: True
print(not x > y) # Salida: True
- Short circuit evaluation
Python uses short circuit evaluation for
andandor:
# 'or' retorna el primer valor verdadero
print("" or "Second" or "Third") # Salida: Second
# 'and' retorna el primer valor falso o el último valor si todos son verdaderos
print(0 and 1) # Salida: 0
print(1 and 2 and 3) # Salida: 3
The Walrus Operator (:=)
Introduced in Python 3.8, the walrus (:=) operator is a powerful feature that allows you to assign values within expressions. This operator gets its name because of its resemblance to the eyes and tusks of a walrus when turned 90 degrees.
The walrus operator performs an assignment and returns the assigned value, allowing the assignment and evaluation to be combined in a single expression. This can lead to more concise and readable code in certain situations.
Example of using the walrus operator:
# Sin operador walrus
n = len([1, 2, 3])
if n > 2:
print(f"La lista tiene {n} elementos")
# Con operador walrus
if (n := len([1, 2, 3])) > 2:
print(f"La lista tiene {n} elementos")
# Salida: La lista tiene 3 elementos
In this example, the walrus operator assigns the result of len([1, 2, 3]) to the variable n and then compares n with 2, all on a single line.
It is important to note that, unlike languages like C, Python requires the explicit use of the walrus operator for assignments within expressions. This helps prevent common errors, such as accidentally typing = (assignment) when you intended to use == (comparison).
Another useful example of the walrus operator is in while loops:
# Sin operador walrus
while True:
chunk = file.read(8192)
if not chunk:
break
process(chunk)
# Con operador walrus
while (chunk := file.read(8192)):
process(chunk)
The walrus operator can make code more concise, but it is important to use it sparingly to maintain readability.
Comparisons of Sequences and Other Types
Python allows you to compare sequences and other types of objects in an intuitive way. When comparing sequences of the same type, Python uses a lexicographic order:
-
The first two elements are compared.
-
If they are different, this determines the result of the comparison.
-
If they are equal, the next two elements are compared.
-
This process continues until reaching the end of one of the sequences.
print((1, 2, 3) < (1, 2, 4)) # True
print([1, 2, 3] < [1, 2, 4]) # True
print('ABC' < 'C' < 'Pascal' < 'Python') # True
print((1, 2, 3, 4) < (1, 2, 4)) # True
print((1, 2) < (1, 2, -1)) # True
It is important to note that comparisons between different types of objects are possible as long as the objects have compatible comparison methods. For example, you can compare numbers of different types (integers, floats) based on their numerical value.
print(0 == 0.0) # True
print(1 < 1.5) # True
However, comparing incompatible types (such as a string with a number) will result in a TypeError:
# Esto lanzará un TypeError
# print("2" < 1)
Lexicographic Comparison
-
If two elements to be compared are both sequences of the same type, the lexicographic comparison is recursive.
-
If all elements of two sequences are equal, the sequences are considered equal.
-
If one sequence is the initial part of the other, the shorter sequence is considered shorter.
For character strings, lexicographic sorting uses the Unicode code point to sort individual characters.
- Examples of Comparisons
print((1, 2, 3) < (1, 2, 4)) # True
print([1, 2, 3] < [1, 2, 4]) # True
print('ABC' < 'C' < 'Pascal' < 'Python') # True
print((1, 2, 3, 4) < (1, 2, 4)) # True
print((1, 2) < (1, 2, -1)) # True
print((1, 2, 3) == (1.0, 2.0, 3.0)) # True
print((1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)) # True
Between Different Types
It is legal to compare objects of different types with < or > as long as the objects have the appropriate comparison methods. For example:
-
Mixed number types are compared according to their numerical value (0 equals 0.0).
-
If the objects do not have supported comparison methods, instead of providing arbitrary sorting, the interpreter will throw a
TypeErrorexception.
print(0 == 0.0) # True
print(1 < 1.5) # True
# Esto lanzará un TypeError
# print("2" < 1)
Conclusion: Mastering Data Structures in Python
The journey through data structures in Python that we have taken in this tutorial reveals the richness and flexibility that this language offers programmers. From versatile lists to efficient dictionaries, Python provides a set of powerful tools that, when mastered, can significantly raise the quality and efficiency of our code.
Lists, with their mutable nature and multiple methods, stand as the backbone of many operations in Python. Their ability to grow, shrink, and morph makes them the perfect canvas for dynamic data manipulation. The elegance of list comprehensions allows us to condense complex operations into concise, readable expressions, demonstrating Python’s philosophy of favoring clarity and expressiveness.
Meanwhile, tuples remind us of the importance of immutability in certain contexts, offering a guarantee of data integrity that can be crucial in applications where consistency is paramount. Sets, for their part, shine in scenarios where uniqueness and set mathematical operations are essential, allowing us to manipulate data with an efficiency that would be difficult to achieve with other structures.
Dictionaries emerge as a jewel in Python’s crown, offering a perfect symbiosis between flexibility and performance. Their ability to efficiently associate keys with values makes them the ideal choice for a wide range of applications, from data caching to representing complex structures.
The iteration techniques and subtleties of comparisons in Python that we have explored are not mere technical details, but tools that, when applied skillfully, can transform verbose code into elegant and efficient expressions. The walrus (:=) operator, for example, illustrates how Python continues to evolve to offer programmers more powerful and concise ways to express their intentions.
Mastering these data structures and their associated operations is not simply a matter of technical knowledge; It is a crucial step towards fluency in Python. With this fluency comes the ability to write code that not only works, but is efficient, maintainable, and elegant. Each framework we’ve discussed has its place in the Python ecosystem, and knowing when and how to use each one is what separates a competent programmer from a true code craftsman.
As you continue your journey into the world of Python, we encourage you to view these data structures not just as tools, but as fundamental pieces of an expressive language. Experiment with them, combine them in creative ways, and above all, use them to solve real problems. Remember that true mastery comes with practice and application.
With the knowledge you’ve gained in this tutorial, you’re well equipped to take on more complex programming challenges. The data structures we have explored are the foundation upon which sophisticated algorithms and robust applications are built. Your understanding of these structures will allow you to not only read and understand advanced Python code, but also design elegant solutions to complex problems.
As you progress in your learning, always keep the Zen of Python in mind: simplicity is better than complexity, but explicit complexity is better than implicit complexity. The data structures you’ve learned will help you navigate this balance, allowing you to write code that is both powerful and understandable.
Mastering data structures in Python is not the end of your journey, but the beginning of infinite possibilities. With these tools at your disposal, you’re ready to create, innovate, and leave your mark on the world of programming. Go ahead, and may your codes always be clear, efficient and pythonic!
Slogans
We have acquired valuable knowledge and have the necessary resources at our disposal. Now is the time to apply what you have learned and start creating. GitHub repository
Lists(7)
-
Duplicate Remover: Write a function that removes all duplicate elements from a list, maintaining the original order of the elements.
- Use a for loop and the append() method for this exercise.
- If the list is empty, use the pass statement to handle this case.
-
Odd and Even Separator: Create a program that generates a list of 20 random numbers between 1 and 100, then divide this list into two: one with even numbers and one with odd numbers.
- Use the random.randint() function to generate random numbers.
- Use list comprehension to separate even and odd numbers.
-
Word Capitalizer: Implement a function that takes a list of strings and returns a new list where each word has the first letter capitalized.
- Use the capitalize() method and a list comprehension for this exercise.
- If the list contains elements that are not strings, the program must handle this situation appropriately.
-
Product of all except self: Create a function that takes a list of numbers and returns a new list where each element is the product of all the numbers in the original list except the number at that position.
- Use two nested for loops for this exercise.
- Handles the case of a list with zeros appropriately.
-
Card Dealer: Implements a function that simulates a card game: given a list of “cards” (they can be numbers or strings), it “deals” a hand of n cards (that is, it removes n random elements from the list and returns them).
- Use the random module and the pop() method for this exercise.
- If n is greater than the number of cards available, use a raise statement to throw an exception.
-
Near Point Finder: Given a list of (x, y) coordinates represented as tuples, find the two points closest to each other.
- Use nested loops and the Euclidean distance formula for this exercise.
- Use the enumerate() function to iterate over the list of coordinates.
-
List Flattener: Create a recursive function that “flattens” a nested list. For example, convert [1, [2, 3, [4, 5]], 6] to [1, 2, 3, 4, 5, 6].
- Use recursion and the list concatenation operator (+) for this exercise.
- Use
isinstance()to check if an element is a list.
List Comprehensions(7)
-
Perfect Squares Generator: Create a list comprehension that generates the first 20 perfect squares.
- Use the range() function and the exponentiation operator (**) for this exercise.
- Make sure the resulting list contains exactly 20 items.
-
Filter words by length: Given a list of words, create a list comprehension that filters only words that are longer than 5 letters.
- Use the len() function to determine the length of each word.
- If the original list is empty, the comprehension should return an empty list.
-
Temperature Transformer: Create a list comprehension that converts a list of temperatures in Celsius to Fahrenheit.
- Use the formula (C * 9/5) + 32 for the conversion.
- Round the results to two decimal places using the round() function.
-
Digit Extractor: Given a list of integers, create a list comprehension that extracts all unique digits used in these numbers.
- Use the str() function to convert numbers to strings.
- Use a set() inside the comprehension to remove duplicates.
-
Coordinate Generator: Create a list comprehension that generates all (x,y) coordinates in a 5x5 grid.
- Use nested list comprehensions for this exercise.
- The result must be a list of tuples (x, y).
-
Dictionary Filter: Given a list of dictionaries representing people with ‘name’ and ‘age’, create a list comprehension that filters only people over 18 years old.
- Use the ‘age’ key to filter the dictionaries.
- The result should be a list of dictionaries.
-
Identity Matrix Generator: Create a list comprehension that generates an identity matrix of size n x n.
- Use nested list comprehensions and the ternary operator for this exercise.
- The parameter n must be provided by the user.
Del(7)
-
Even Element Remover: Write a function that removes all elements at even positions in a list (indexes 0, 2, 4, etc.).
- It uses a reverse for loop and the del statement.
- Make sure you handle the case of an empty list correctly.
-
Dictionary Cleaner: Create a function that removes all keys from a dictionary whose values are None.
- Use a for loop to iterate over a copy of the dictionary keys.
- Use the del statement to remove keys with None values.
-
List Reducer: Implement a function that reduces a list to its first n elements, eliminating the rest.
- Use slicing and the instruction for this exercise.
- If n is greater than the length of the list, the function should not modify the list.
-
Variable Remover: Write a program that creates multiple variables and then removes them one by one, printing the local namespace after each removal.
- Use the locals() function to print the namespace.
- Handles exceptions that may arise when trying to access deleted variables.
-
Attribute Cleaner: Creates a class with multiple attributes and a method that removes all attributes from the instance except a specified one.
- Use vars() to get a dictionary of the instance attributes.
- Use a for loop and the del statement to remove the attributes.
-
Substring Remover: Implements a function that removes all occurrences of a given substring in a parent string.
- Converts the string to a list of characters.
- Use slicing and the del statement to remove any substrings found.
-
Memory Manager: Create a program that simulates memory management, where you can “allocate” and “free” blocks of memory.
- It uses a dictionary to represent memory, where keys are addresses and values are data.
- Implements functions to “allocate” (add to dictionary) and “free” (use del to remove from dictionary) blocks of memory.
Tuples(7)
-
Value Swapper: Write a function that takes two variables and swaps their values using a tuple.
- Use multiple assignment with a tuple to perform the exchange.
- Make sure the function works with different types of data.
-
Tuple Unpacker: Create a function that takes a list of tuples (name, age, profession) and returns three separate lists with the names, ages, and professions.
- It uses tuple unpacking and list comprehension.
- Handles the case where some tuple does not have exactly three elements.
-
Tuple sorter: Implements a function that sorts a list of tuples based on the second element of each tuple.
- Use the sorted() function with a custom key argument.
- If the second element is the same, sort by the first element.
-
Occurrence Counter: Write a function that counts the occurrences of each element in a tuple and returns a dictionary with the results.
- Use a dictionary to store the counts.
- Handles the case of tuples containing non-hashable elements.
-
N-gram generator: Create a function that generates all possible n-grams from a given sequence (can be a list, tuple or string).
- Use zip() and slicing to generate the n-grams.
- Allows the function to accept a parameter to specify the size of the n-grams.
-
Tuple Filter: Implements a function that filters a list of tuples based on a given condition (for example, tuples where the first element is even).
- Use filter() or a list comprehension to perform filtering.
- Allows the function to accept the filter condition as an argument.
-
Tuple Merger: Write a function that takes two tuples and returns a new tuple that is the fusion of both, eliminating duplicates and maintaining the order.
- Use set() to remove duplicates and then convert back to tuple.
- Make sure that the order of the elements in the resulting tuple is the same as in the original tuples.
Sets(7)
-
Duplicate Remover: Write a function that takes a list as input and returns a new list with no duplicate elements, maintaining the original order of appearance.
- Use a set to eliminate duplicates efficiently.
- Converts the result back to a list to maintain the original order.
-
Intersection Calculator: Create a function that takes two lists as input and returns a new list with the elements common to both, without duplicates.
- Converts input lists to sets.
- Use the intersection() method to find common elements.
-
Subset Checker: Implements a function that determines whether all elements of a list are present in another list, regardless of the order or number of repetitions.
- Converts both lists to sets.
- Use the issubset() method to check if one set is a subset of the other.
-
Set Power Generator: Write a function that generates all possible subsets of a given set.
- Use the itertools library to generate all possible combinations.
- Returns the result as a list of sets.
-
Symmetric Difference Calculator: Create a function that takes two sets as input and returns a new set with elements that are in either set, but not both.
- Use the ^ (XOR) operator for sets or the symmetric_difference() method.
- Make sure the function handles empty sets correctly.
-
Disjunction Checker: Implements a function that determines if two lists have no elements in common.
- Convert lists to sets.
- Use the isdisjoint() method to check if the sets are disjoint.
-
Search Optimizer: Create a function that takes a large list and a small list, and efficiently determines if all the items in the small list are in the large list.
- Converts the big list to a set for O(1) searches.
- Iterates over the small list, checking for membership in the set.
Dictionaries(7)
-
Word Counter: Write a function that takes a text string and returns a dictionary where the keys are the unique words and the values are the number of times each word appears.
- Use the split() method to split the text into words.
- Use a dictionary to count the occurrences of each word.
-
Dictionary Merger: Create a function that takes two dictionaries and merges them into one. If there are duplicate keys, the value from the second dictionary should prevail.
- Use the update() method or a dictionary comprehension to combine the dictionaries.
- Make sure you don’t modify the original dictionaries.
-
Dictionary inverter: Implement a function that takes a dictionary and returns a new dictionary where the keys and values are exchanged.
- Handles the case where multiple keys have the same value.
- Use a dictionary comprehension to create the new dictionary.
-
Maximum Value Finder: Write a function that finds the key(s) with the highest value in a dictionary.
- Use the max() function with a custom key argument.
- Returns a list of keys in case there are multiple maximum values.
-
Nested Dictionary Flattener: Create a recursive function that “flattens” a nested dictionary, where the keys of the new dictionary are the paths to the values in the original dictionary.
- Use recursion to handle dictionaries nested to any depth.
- The keys of the flattened dictionary must be strings that represent the path (for example, “a.b.c”).
-
Dictionary Filter: Implements a function that filters a dictionary based on a predicate function that is applied to the values.
- The function must accept the dictionary and a predicate function as arguments.
- Use a dictionary comprehension to create the new filtered dictionary.
-
Dictionary Sorter by Values: Write a function that sorts a dictionary based on its values and returns a list of sorted (key, value) tuples.
- Use the sorted() function with a custom key argument.
- Allows the function to accept an argument to specify ascending or descending order.
Iteration Techniques(7)
-
Dictionary Iterator: Write a function that takes a dictionary and prints its keys and values in “key:value” format using a for loop and the items() method.
- Use tuple unpacking in the for loop.
- Handles the case of an empty dictionary.
-
List Enumerator: Create a function that takes a list and prints each element along with its index using the enumerate() function.
- The print format should be “Index: X, Value: Y”.
- Allows the function to accept an optional parameter to specify the starting index.
-
Multiple list iterator: Implements a function that takes two or more lists of equal length and iterates them in parallel using zip(), printing the corresponding elements.
- Use *args to allow a variable number of lists as input.
- Handles the case where lists have different lengths.
-
Reverse Iterator: Write a function that iterates over a sequence in reverse order using reversed() and prints each element.
- The function must work with lists, tuples and strings.
- Includes an optional parameter to specify how many elements to invest.
-
Array Iterator: Create a function that iterates over an array (list of lists) and prints each element along with its row and column indexes.
- Use nested for loops and enumerate() for this exercise.
- Formats the output as “Item in (row, column): value.”
-
File Iterator: Implements a function that reads a file line by line and prints each line preceded by its line number.
- Use enumerate() to get the line number.
- Properly handles file opening and closing.
-
Custom Iterator: Create a class that implements a custom iterator that outputs the first n numbers of the Fibonacci sequence.
- Implements the iter() and next() methods.
- Throw StopIteration when limit n is reached.
Conditions(7)
-
Range Checker: Write a function that takes a number and checks if it is within a specific range (for example, between 0 and 100, inclusive).
- Use chained comparison operators.
- Returns True if in range, False otherwise.
-
Triangle Classifier: Create a function that takes the lengths of three sides and determines whether they form an equilateral, isosceles, or scalene triangle.
- Use multiple if-elif-else conditions.
- Check first if the sides can form a valid triangle.
-
Logical Expression Evaluator: Implements a function that takes three boolean values and evaluates a complex logical expression.
- Use and, or, and not operators.
- Includes parentheses to control the order of evaluation.
-
Sequence Comparator: Write a function that compares two sequences (lists, tuples, or strings) and determines their relationship (equal, subset, superset, or no relationship).
- Use comparison operators for sequences.
- Handles the case of different sequence types.
-
Leap Year Checker: Create a function that determines if a given year is a leap year.
- A year is a leap year if it is divisible by 4, except those divisible by 100 which are not divisible by 400.
- Use comparison operators and logical operators to build the condition.
-
Password Evaluator: Implement a function that evaluates the strength of a password based on multiple criteria (length, presence of uppercase, lowercase, numbers and special characters).
- It uses multiple conditions and the in operator to check for the presence of character types.
- Returns a rating (for example, “weak”, “medium”, “strong”) based on how many criteria it meets.
-
Discount Calculator: Write a function that calculates the discount applicable to a purchase based on multiple conditions (purchase amount, day of the week, whether the customer is a member, etc.).
- Uses a combination of nested conditions and logical operators.
- Implement at least three discount levels based on different combinations of conditions.
Walrus Operator(7)
-
Element Finder: Write a function that searches for an element in a list and, if found, prints its position. Use the walrus operator in a while loop.
- Use the index() method within the while condition with the walrus operator.
- If the item is not found, print an appropriate message.
-
Input Validator: Create a program that prompts the user to enter a number between 1 and 10, using the walrus operator in a while loop to validate the input.
- Use input() with the walrus operator in the while condition.
- Convert the input to int and check if it is in the correct range.
-
String Processor: Implements a function that processes a string as long as its length is greater than zero, using the walrus operator to assign and check the length at each iteration.
- Use len() with the walrus operator in the while condition.
- On each iteration, remove the first character from the string and process it in some way.
-
Statistics Calculator: Write a program that calculates the mean of a series of numbers entered by the user, using the walrus operator to assign and verify each entry.
- Use input() with the walrus operator to get numbers until the user enters an empty string.
- Calculates and displays the average of the numbers entered.
-
Sequence Generator: Create a generator function that produces a sequence of numbers, using the walrus operator to update and check the state of the generator.
- Use the walrus operator in the condition of a while loop inside the generator.
- The sequence must end when a certain value or condition is reached.
-
List Parser: Implements a function that parses a list of elements, using the walrus operator to assign and verify properties of each element in a for loop.
- Use the walrus operator to assign the result of a check function to a variable.
- Perform different actions based on the result of the check.
-
Efficient file reader: Write a function that reads a file line by line, processing only the lines that meet a certain condition, using the walrus operator to assign and verify each line read.
- Use the readline() method with the walrus operator in a while loop.
- Processes lines that meet the specified condition.
Comparisons of Sequences and Other Types (7)
-
List Comparator: Write a function that compares two lists and determines if they are equal, regardless of the order of the elements.
- Use conversion to sets to compare content.
- The function should return True if the lists have the same elements, False otherwise.
-
Lexicographic Sorter: Implements a function that sorts a list of strings in lexicographic order.
- Use the sorted() function with a custom key if necessary.
- Make sure the function handles upper and lower case correctly.
-
Tuple Comparator: Create a function that compares two tuples and determines which one is “larger” based on lexicographic order.
- The function should return -1 if the first tuple is smaller, 0 if they are equal, and 1 if the first is larger.
- Handles the case of tuples of different lengths.
-
Substring Finder: Write a function that determines if one string is a substring of another, using only comparison operators.
- Don’t use string methods like find() or in.
- The function should return the index where the substring begins, or -1 if not found.
-
Version Comparator: Implements a function that compares two version numbers (for example, “1.2.3” and “1.2.4”) and determines which is higher.
- Split the strings into components and compare them one by one.
- Correctly handle versions with different numbers of components.
-
Custom Sorter: Create a function that sorts a list of custom objects based on multiple criteria.
- Defines a class with at least three attributes.
- Implement a lt() method in the class to allow comparison.
- Use sorted() with a key that uses tuples for multi-criteria comparison.
-
Nested Structure Compare: Write a function that compares two nested data structures (which can contain lists, tuples, and dictionaries) and determines if they are equal.
- The function must be recursive to handle structures of any depth.
- Make sure the function correctly handles different types of collections.
Sections covered today
-
- 5.1. More about lists
- 5.1.1. Use lists as stacks
- 5.1.2. Use lists as queues
- 5.1.3. List Comprehension
- 5.1.4. Nested List Comprehensions
- 5.2. The instruction of
- 5.3. Tuples and sequences
- 5.4. Sets
- 5.5. Dictionaries
- 5.6. Iteration techniques
- 5.7. More about conditions
- 5.8. Comparing sequences and other types
- 5.1. More about lists
Related articles
- Python tutorial #4: The key to organizing and reusing your code >>
- << Python Tutorial #2: Advanced Flow Control and Functions