Variables of list type have many methods that can help us work with a list. Suppose we have a list named foos, and the list has a method named bar, then the syntax for using that list method is foos.bar(). This is the syntax for calling an object's method through an object reference. Later, when we talk about object-oriented programming, we will explain this syntax in more detail. This syntax can also be described as sending a message to an object.
A list is a mutable container. A mutable container means we can add elements to it, remove elements from it, and also modify the elements that are already inside it.
We can use the append method of a list to add an element to the end of the list, and use the insert method to insert an element into the list. Appending means adding the element to the end of the list, while inserting means adding a new element at a specified position. Look at the code below.
languages = ['Python', 'Java', 'C++']
languages.append('JavaScript')
print(languages) # ['Python', 'Java', 'C++', 'JavaScript']
languages.insert(1, 'SQL')
print(languages) # ['Python', 'SQL', 'Java', 'C++', 'JavaScript']We can use the remove method of a list to delete a specified element from the list. Note that if the element to be deleted is not in the list, it raises ValueError and causes the program to crash. So when deleting an element, it is recommended that you first use the membership operation we learned earlier to check. We can also use the pop method to remove elements from the list. By default, pop deletes the last element in the list, but of course you can also give it a position and delete the element at the specified position. When using pop, if the index is out of range, it raises IndexError and causes the program to crash. In addition, the list has a clear method, which clears all elements in the list, as shown below.
languages = ['Python', 'SQL', 'Java', 'C++', 'JavaScript']
if 'Java' in languages:
languages.remove('Java')
if 'Swift' in languages:
languages.remove('Swift')
print(languages) # ['Python', 'SQL', 'C++', 'JavaScript']
languages.pop()
temp = languages.pop(1)
print(temp) # SQL
languages.append(temp)
print(languages) # ['Python', 'C++', 'SQL']
languages.clear()
print(languages) # []Note:
popreturns the removed element. In the example above, we store the result intemp, and then add it back later. Of course, if you want, you can put the removed element back into the list, just likelanguages.append(temp)does in the code above.
Here is one small question. If the languages list contains multiple 'Python' values, then when we use languages.remove('Python'), does it delete all 'Python' values or only the first one? You can guess first and then try it yourself.
There is actually another way to delete elements from a list: use Python's del keyword followed by the element to be deleted. In essence, this is not different from using pop with a specified index, but pop returns the deleted element, while del is slightly better in performance. That is because the underlying bytecode instruction corresponding to del is DELETE_SUBSCR, while the bytecode instructions corresponding to pop are CALL_METHOD and POP_TOP. If you do not understand this yet, just ignore it.
items = ['Python', 'Java', 'C++']
del items[1]
print(items) # ['Python', 'C++']The index method of a list can find the index position of an element in the list. If the specified element cannot be found, the index method raises ValueError. The count method of a list can count how many times an element appears in the list, as shown below.
items = ['Python', 'Java', 'Java', 'C++', 'Kotlin', 'Python']
print(items.index('Python')) # 0
print(items.index('Python', 1)) # 5
print(items.count('Python')) # 2
print(items.count('Kotlin')) # 1
print(items.count('Swift')) # 0
# print(items.index('Java', 3)) # ValueError: 'Java' is not in listThe sort method of a list can sort the list elements, and the reverse method can reverse the elements, as shown below.
items = ['Python', 'Java', 'C++', 'Kotlin', 'Swift']
items.sort()
print(items) # ['C++', 'Java', 'Kotlin', 'Python', 'Swift']
items.reverse()
print(items) # ['Swift', 'Python', 'Kotlin', 'Java', 'C++']In Python, a list can also be created through a special literal syntax. This syntax is called a comprehension. Below, we use examples to explain what benefits list comprehensions bring.
Scenario 1: create a list of numbers from 1 to 99 that are divisible by 3 or 5.
items = []
for i in range(1, 100):
if i % 3 == 0 or i % 5 == 0:
items.append(i)
print(items)Using a list comprehension to do the same thing:
items = [i for i in range(1, 100) if i % 3 == 0 or i % 5 == 0]
print(items)Scenario 2: given a list of integers nums1, create a new list nums2 whose elements are the squares of the corresponding elements in nums1.
nums1 = [35, 12, 97, 64, 55]
nums2 = []
for num in nums1:
nums2.append(num ** 2)
print(nums2)Using a list comprehension to do the same thing:
nums1 = [35, 12, 97, 64, 55]
nums2 = [num ** 2 for num in nums1]
print(nums2)Scenario 3: given a list of integers nums1, create a new list nums2 and put into it the elements in nums1 that are greater than 50.
nums1 = [35, 12, 97, 64, 55]
nums2 = []
for num in nums1:
if num > 50:
nums2.append(num)
print(nums2)Using a list comprehension to do the same thing:
nums1 = [35, 12, 97, 64, 55]
nums2 = [num for num in nums1 if num > 50]
print(nums2)Using list comprehensions to create lists is not only simple and elegant, but also faster than using a for-in loop and the append method to keep adding elements to an empty list. Why do comprehensions perform better? That is because Python bytecode has instructions specially prepared for comprehensions, such as the LIST_APPEND instruction. But a for loop adds elements to a list through method calls, represented by instructions such as LOAD_METHOD and CALL_METHOD, and method calls themselves are relatively time-consuming. It does not matter if you do not understand this point. Just remember the conclusion: it is strongly recommended to use comprehension syntax to create lists.
Python does not require the elements in a list to have the same data type. In other words, the elements in a list can be any data type, and of course this includes lists themselves. If the elements in a list are also lists, then we can call it a nested list. A nested list can be used to represent a table or a matrix in mathematics. For example, if we want to store the scores of 5 students in 3 courses, we can use the list below.
scores = [[95, 83, 92], [80, 75, 82], [92, 97, 90], [80, 78, 69], [65, 66, 89]]
print(scores[0])
print(scores[0][1])For the nested list above, each element is the scores of one student in 3 courses, such as [95, 83, 92]. The 83 in that list is the score of one course for that student. If you want to access that value, you need to use indexing twice: scores[0][1]. First, scores[0] gets the list [95, 83, 92], and then [1] gets the second element in that list.
If you want to enter the scores from the keyboard and store them in a list, you can use the code below.
scores = []
for _ in range(5):
temp = []
for _ in range(3):
score = int(input('Enter score: '))
temp.append(score)
scores.append(temp)
print(scores)If you want to generate the scores randomly and store them in a list, we can use a list comprehension, as shown below.
import random
scores = [[random.randrange(60, 101) for _ in range(3)] for _ in range(5)]
print(scores)Note: The code
[random.randrange(60, 101) for _ in range(3)]creates a list of 3 random integers. Then we put this code inside another list comprehension as list elements. In this way, 5 such elements are generated, and the final result is a nested list.
Below, let us use an example of randomly generating numbers for the "Double Color Ball" lottery to explain the application of lists. Double Color Ball is a lotto-style lottery issued by the China Welfare Lottery Issuance and Management Center. Each bet number consists of 6 red balls and 1 blue ball. Red ball numbers are chosen from 1 to 33, and the blue ball number is chosen from 1 to 16. Each bet needs 6 red-ball numbers and 1 blue-ball number, as shown below.
Tip: There is a very sharp description on Zhihu about the essence of lottery: "Invent an imaginary person who gets rich without working, use that to fool a group of people who also want to get rich without working, and in the end support a group of people who truly get rich without working." Many people who have no idea about probability even think the chance of winning and not winning is 50-50. Many others think that if the chance of winning is 1%, then buying 100 times guarantees a win. These are all absurd ideas. So, cherish life and stay away from gambling, especially when you know nothing about probability.
Now, let us use a Python program to generate one set of random numbers.
"""
Random number generator for Double Color Ball
Author: Luo Hao
Version: 1.0
"""
import random
red_balls = list(range(1, 34))
selected_balls = []
# Add 6 red balls to the selected list.
for _ in range(6):
# Generate a random integer representing the index of the selected red ball.
index = random.randrange(len(red_balls))
# Remove the selected ball from the red-ball list and add it to the selected list.
selected_balls.append(red_balls.pop(index))
# Sort the selected red balls.
selected_balls.sort()
# Print the red balls.
for ball in selected_balls:
print(f'\033[031m{ball:0>2d}\033[0m', end=' ')
# Randomly choose 1 blue ball.
blue_ball = random.randrange(1, 17)
# Print the blue ball.
print(f'\033[034m{blue_ball:0>2d}\033[0m')Note: In the code above,
print(f'\033[0m...\033[0m')is used to control the output color, so the red balls are printed in red and the blue ball is printed in blue. The...stands for the content we want to print.\033[0mis a control code that turns off all attributes, so the previous control code stops working. You can also think of it simply as a separator. The0beforemmeans the default display mode in the terminal. That0can be omitted.1means highlight,5means blink,7means reverse video, and so on. Between0andm, we can put a color number, such as30for black,31for red,32for green,33for yellow, and34for blue.
We can also use the sample and choice functions provided by the random module to simplify the code above. The former can do random sampling without replacement, and the latter can randomly choose one element. The modified code is shown below.
"""
Random number generator for Double Color Ball
Author: Luo Hao
Version: 1.1
"""
import random
red_balls = [i for i in range(1, 34)]
blue_balls = [i for i in range(1, 17)]
# Randomly choose 6 red balls from the red-ball list (sampling without replacement).
selected_balls = random.sample(red_balls, 6)
# Sort the selected red balls.
selected_balls.sort()
# Print the red balls.
for ball in selected_balls:
print(f'\033[031m{ball:0>2d}\033[0m', end=' ')
# Randomly choose 1 blue ball from the blue-ball list.
blue_ball = random.choice(blue_balls)
# Print the blue ball.
print(f'\033[034m{blue_ball:0>2d}\033[0m')If we want to randomly generate N bets, we only need to put the code above into a loop that runs N times, as shown below.
"""
Random number generator for Double Color Ball
Author: Luo Hao
Version: 1.2
"""
import random
n = int(input('How many tickets to generate: '))
red_balls = [i for i in range(1, 34)]
blue_balls = [i for i in range(1, 17)]
for _ in range(n):
# Randomly choose 6 red balls from the red-ball list (sampling without replacement).
selected_balls = random.sample(red_balls, 6)
# Sort the selected red balls.
selected_balls.sort()
# Print the red balls.
for ball in selected_balls:
print(f'\033[031m{ball:0>2d}\033[0m', end=' ')
# Randomly choose 1 blue ball from the blue-ball list.
blue_ball = random.choice(blue_balls)
# Print the blue ball.
print(f'\033[034m{blue_ball:0>2d}\033[0m')When we run the code above in PyCharm, enter 5, and start the program, the result looks like the picture below.
Here, let me also introduce a third-party Python library named rich. It can help us produce beautiful output in the simplest way. You can install this library in the terminal by using Python's package management tool pip. For PyCharm users, of course you should run the pip command in PyCharm's terminal window, so that rich is installed into the virtual environment of the project. The command is shown below.
pip install richAs shown in the picture above, after rich is installed successfully, we can use the following code to control the output.
"""
Random number generator for Double Color Ball
Author: Luo Hao
Version: 1.3
"""
import random
from rich.console import Console
from rich.table import Table
# Create the console.
console = Console()
n = int(input('How many tickets to generate: '))
red_balls = [i for i in range(1, 34)]
blue_balls = [i for i in range(1, 17)]
# Create the table and add the header.
table = Table(show_header=True)
for col_name in ('No.', 'Red Balls', 'Blue Ball'):
table.add_column(col_name, justify='center')
for i in range(n):
selected_balls = random.sample(red_balls, 6)
selected_balls.sort()
blue_ball = random.choice(blue_balls)
# Add a row to the table: serial number, red balls, blue ball.
table.add_row(
str(i + 1),
f'[red]{" ".join([f"{ball:0>2d}" for ball in selected_balls])}[/red]',
f'[blue]{blue_ball:0>2d}[/blue]'
)
# Output the table through the console.
console.print(table)Note: In line 31 of the code above, a list comprehension is used to turn the red-ball numbers into strings and store them in a list.
" ".join([...])joins multiple strings in the list into one complete string with spaces. If you do not understand that yet, you can leave it for now. The[red]...[/red]in the string is used to set the output color to red, and[blue]...[/blue]on the next line is used to set the output color to blue. For more information about therichlibrary, you can read the official documentation.
The final output is shown in the picture below. Looking at output like this, does your mood become a little better too?
In Python, the underlying structure of a list is an array that can grow dynamically. List elements are stored continuously in computer memory, so random access can be achieved, which means we can get the corresponding element through a valid index, and the operation time does not depend on how many elements are in the list. We can leave these storage details alone for now, and there is no need for everyone to understand the asymptotic time complexity of every list method yet, meaning the relationship between the time used by a method and the number of list elements. I think it is more important that everyone first learn how to use lists to solve problems in real work.



