列表推导式
列表推导式是Python中快速生成列表的一种方法,它允许你使用可迭代对象快速生成一个列表,可以替代简单的循环语句。
基本结构:[expression for item in iterable if condition]
- expression:基于迭代变量,可以是任何Python表达式,如元组,集合等。
- item:迭代器返回的项目。
- iterable:Python中可迭代对象,包括有内置的五个数据结构,文件对象,生成器,以及其他内置迭代器(如,range,zip,map,filter等),还有自定义迭代器,外部库中的可迭代对象等
- condition:可选的条件语句。
# 包含条件的列表推导式
even_squares = [x*x for x in range(10) if x % 2 == 0]
print(even_squares) # 输出: [0, 4, 16, 36, 64]# 等价下列程序(可根据这个理解)
even_squares = []
for x in range(10):if x % 2 == 0:even_squares.append(x*x)print(even_squares) # 输出: [0, 4, 16, 36, 64]# 使用元组表达式
even_squares = [(x, x*x) for x in range(10) if x % 2 == 0]
print(even_squares) # 输出: [(0, 0), (2, 4), (4, 16), (6, 36), (8, 64)]
除了基本的列表推导式,Python还支持嵌套列表推导式。
你可以在列表推导式中使用多个循环,实现更复杂的迭代逻辑。
# 使用嵌套列表推导式处理二维数组
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]# 它也可以进行拆分理解
迭代器
迭代器是Python中一个实现了迭代器协议的对象,这包括__iter__()
和__next__()
两个方法。迭代器允许程序员在容器(如列表或字典)上进行遍历。
迭代器的工作原理:
__iter__()
方法返回迭代器对象本身。__next__()
方法返回容器的下一个项目。当容器中没有更多元素时,__next__()
应该抛出一个StopIteration
异常。
创建自定义迭代器的示例:
class Countdown:def __init__(self, start):self.current = startdef __iter__(self):return selfdef __next__(self):if self.current <= 0:raise StopIterationelse:num = self.currentself.current -= 1return num# 使用迭代器
counter = Countdown(5)
for num in counter:print(num)
生成器
生成器是一种特殊类型的迭代器,它通过一个包含yield
语句的函数定义。当生成器函数被调用时,它不会立即执行,而是返回一个生成器对象。这个对象在迭代时才真正执行函数内的代码。
每次调用next()
方法(或在for循环中迭代)时,my_generator
函数执行到下一个yield
语句并暂停执行,返回yield后的值。当再次被调用时,从上次离开的地方继续执行。
def my_generator():yield 'a'yield 'b'yield 'c'gen = my_generator()
for value in gen:print(value)
生成器使用迭代来处理数据,这意味着在任何时候内存中只有一个数据项被处理,这个特点使他成为处理大型数据集时的理想选择,例如大型文件或网络流。
def read_large_file(file_name):with open(file_name, 'r') as file:for line in file:yield line.strip()log_lines = read_large_file('large_log_file.log')
for line in log_lines:if "ERROR" in line:print(line)
生成器yield与return之间的比较:
1. return
return
语句用于从函数返回一个值,结束函数的执行。当一个函数执行到return
语句时,函数的局部变量的生命周期结束,控制流返回到函数被调用的地方。
- 终结执行:执行到
return
语句时,函数的执行立即结束。 - 返回值:可以返回一个值或
None
(如果没有指定返回值)。 - 单次使用:函数中可以有多个
return
语句,但只有一个return
语句会被执行。
def sum_two_numbers(a, b):return a + breturn a - bresult = sum_two_numbers(5, 3)
print(result) # 输出: 8
2. yield
yield
语句用于从一个函数返回一个值,并暂停函数的执行,即函数的状态被冻结,包括所有变量的值和指令指针的位置。yield
通常用于创建生成器。
- 暂停执行:
yield
返回一个值后,函数的执行被暂停,保留当前所有变量的状态,直到再次调用时从上次离开的地方继续执行。 - 多次使用:函数可以包含多个
yield
语句。每次通过迭代器请求值时,函数执行到下一个yield
语句并再次暂停。 - 不终结执行:使用
yield
的函数在提供值后,并未完全结束,而是等待下一次迭代。
def count_down(start):while start > 0:yield startstart -= 1for number in count_down(5):print(number)
# 输出:
# 5
# 4
# 3
# 2
# 1
生成器表达式
生成器表达式提供了一种语法更为紧凑的方式来创建生成器,它们的语法和列表推导式非常相似,但使用圆括号而不是方括号。生成器表达式适用于快速生成数据而不需要存储全部数据的情况。
基本结构:(expression for item in iterable if condition)
- expression:基于迭代变量,可以是任何Python表达式,如元组,集合等。
- item:迭代器返回的项目。
- iterable:Python中可迭代对象,包括有内置的五个数据结构,文件对象,生成器,以及其他内置迭代器(如,range,zip,map,filter等),还有自定义迭代器,外部库中的可迭代对象等
- condition:可选的条件语句。
squares = (x*x for x in range(10))
for square in squares:print(square, end=" ")
# 0 1 4 9 16 25 36 49 64 81
列表推导式与生成表达式的比较:
# 列表推导式
square_list = [x*x for x in range(10)]
# 生成器表达式
square_gen = (x*x for x in range(10))
- 当你使用列表推导式时,Python会立即执行其中的表达式,生成列表中的所有元素,并将这些元素存储在内存中。这使得列表推导式非常快,因为它立即提供了一个完整的列表,但这种方法也可能消耗大量内存,特别是当列表非常大时。
- 生成表达式则是返回一个生成器对象,该对象按需生成元素。这意味着元素只有在迭代时才被计算的,而不是在生成器表达式被定义时。这种方法可以显著降低内存使用,因为在任何时刻,只有一个元素被存储在内存中。