学习python的第十五天之数据类型——推导式
列表推导式
列表推导式(List Comprehension)是 Python 提供的一种简洁的创建列表的方式,它允许通过一个表达式来创建列表,并且可以用 for 循环来迭代任何可迭代对象,还可以使用条件判断来筛选元素。
语法:[表达式 for item in 可迭代对象 if 条件]
表达式
:表示对每个元素进行的处理操作,可以是简单的数学运算、函数调用等。item
:表示从可迭代对象中取出的每个元素。可迭代对象
:可以是一个列表、元组、集合、字典(此时会迭代字典的键)、字符串等。条件
:可选,用于筛选满足条件的元素。
# 创建一个包含 1 到 10 之间所有整数的列表
numbers = [i for i in range(1, 11)]
print(numbers) # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 创建一个包含 1 到 10 之间所有整数的平方的列表
squares = [i**2 for i in range(1, 11)]
print(squares) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 筛选出 1 到 10 之间的所有偶数,并创建一个包含这些偶数的列表
evens = [i for i in range(1, 11) if i % 2 == 0]
print(evens) # 输出: [2, 4, 6, 8, 10]
# 将一个字符串列表中的每个字符串转换为小写,并去除空格
fruits = ["Apple", "Banana", "Cherry"]
lowercase_fruits = [fruit.lower().strip() for fruit in fruits]
print(lowercase_fruits) # 输出: ['apple', 'banana', 'cherry']
# 使用列表推导式创建一个包含嵌套列表元素的平铺列表(即将嵌套列表展开)
nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened_list = [num for sublist in nested_list for num in sublist]
print(flattened_list) # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 根据条件添加不同的前缀
# 假设我们有一个字符串列表,我们想要根据字符串的长度在新列表中给每个字符串添加一个前缀:
# “Short”表示长度小于4,“Long”表示长度大于等于4。
strings = ["apple", "bee", "cat", "dog", "elephant"]
new_strings = ["Short " + s if len(s) < 4 else "Long " + s for s in strings]
print(new_strings) # 输出: ['Short apple', 'Short bee', 'Short cat', 'Long dog', 'Long elephant']
元组推导式
元组推导式(Tuple Comprehension)与列表推导式类似,但生成的是元组而不是列表。元组推导式在语法上使用圆括号
()
而不是方括号[]
。然而,需要注意的是,由于元组是不可变的,元组推导式通常用于生成新的元组,而不是修改现有的元组。语法:(表达式 for item in 可迭代对象 if 条件)
表达式
:表示对每个元素进行的处理操作,可以是简单的数学运算、函数调用等。item
:表示从可迭代对象中取出的每个元素。可迭代对象
:可以是一个列表、元组、集合、字典(此时会迭代字典的键)、字符串等。条件
:可选,用于筛选满足条件的元素。
# 生成一个包含1到5之间所有整数的平方的元组
squares = tuple(i**2 for i in range(1, 6))
print(squares) # 输出: (1, 4, 9, 16, 25)
# 其中负数变为它们的绝对值,非负数保持不变
numbers = [-1, 0, 1, 2, 3]
transformed = tuple(abs(num) if num < 0 else num for num in numbers)
print(transformed) # 输出: (1, 0, 1, 2, 3)
# 每个整数如果是偶数则保持不变,如果是奇数则加1使其变为偶数
numbers = [1, 2, 3, 4, 5]
# 使用元组推导式和if-else条件
even_or_next_even = tuple(num if num % 2 == 0 else num + 1 for num in numbers)
print(even_or_next_even) # 输出: (2, 2, 4, 4, 6)
字典推导式
字典推导式(Dictionary Comprehension)是一种简洁而强大的方式来创建字典。它与列表推导式和元组推导式类似,但生成的是字典而不是列表或元组。
语法:{key_expression: value_expression for item in iterable if condition}
key_expression
: 这是一个表达式,用于生成字典的键。它通常会依赖于循环中的item
,但也可以是完全独立的表达式。value_expression
: 这是一个表达式,用于生成字典的值。它同样通常会依赖于循环中的item
。for item in iterable
: 这是一个循环,用于遍历一个可迭代对象(如列表、元组、集合、字典或任何实现了迭代器协议的对象)。if condition
(可选): 这是一个条件判断,用于过滤哪些元素应该包含在最终的字典中。只有满足条件的元素才会被处理并添加到字典中。
# 从一个列表创建一个字典,其中列表的每个元素都作为字典的键,而元素的长度作为字典的值
words = ["apple", "banana", "cherry"]
word_lengths = {word: len(word) for word in words}
print(word_lengths) # 输出: {'apple': 5, 'banana': 6, 'cherry': 6}
# 只包含长度大于5的单词
words = ["apple", "banana", "cherry", "kiwi"]
long_words = {word: len(word) for word in words if len(word) > 5}
print(long_words) # 输出: {'banana': 6, 'cherry': 6}
# 从一个包含多个字典的列表中提取特定键的值,并创建一个新的字典
students = [
{"name": "Alice", "age": 20, "grades": {"math": 90, "science": 80}},
{"name": "Bob", "age": 22, "grades": {"math": 85, "science": 88}},
{"name": "Charlie", "age": 23, "grades": {"math": 92, "science": 95}}
]
# 提取每个学生的名字和数学成绩
math_grades = {student["name"]: student["grades"]["math"] for student in students}
print(math_grades) # 输出: {'Alice': 90, 'Bob': 85, 'Charlie': 92}
# 创建一个字典,其中键是列表中的每个整数,值是该整数是偶数还是奇数的字符串表示
numbers = [1, 2, 3, 4, 5]
# 使用字典推导式和if-else条件
even_odd_dict = {num: ("Even" if num % 2 == 0 else "Odd") for num in numbers}
print(even_odd_dict) # 输出: {1: 'Odd', 2: 'Even', 3: 'Odd', 4: 'Even', 5: 'Odd'}
注意事项
- 字典推导式会生成一个新的字典对象,而不会修改现有的字典。
- 如果
key_expression
生成的键在字典中已经存在,那么后续的值会覆盖之前的值。 - 字典推导式通常比使用循环和条件语句来创建字典更简洁、更易读。
- 在使用字典推导式时,要注意不要过度复杂化表达式,以免降低代码的可读性。如果表达式变得太复杂,考虑将其拆分成多个步骤或使用辅助函数。
集合推导式
集合推导式(Set Comprehension)与列表推导式和字典推导式类似,它提供了一种简洁而强大的方式来创建集合。集合推导式允许你通过一个表达式来生成集合的成员,通常这个表达式会包含一个循环,有时也会包含条件判断。
语法:{expression for item in iterable if condition}
expression
: 这是一个表达式,用于生成集合的成员。它通常会依赖于循环中的item
。for item in iterable
: 这是一个循环,用于遍历一个可迭代对象(如列表、元组、集合、字典的键或任何实现了迭代器协议的对象)。if condition
(可选): 这是一个条件判断,用于过滤哪些元素应该包含在最终的集合中。只有满足条件的元素才会被添加到集合中。
# 从列表创建集合,包含列表中的所有元素
numbers = [1, 2, 3, 4, 5]
number_set = {x for x in numbers}
# 输出: {1, 2, 3, 4, 5}
# 从列表创建集合,但只包含偶数元素
numbers = [1, 2, 3, 4, 5]
even_set = {x for x in numbers if x % 2 == 0}
# 输出: {2, 4}
# 从字典的键创建集合
student_scores = {"Alice": 90, "Bob": 85, "Charlie": 92}
student_set = {name for name in student_scores}
# 输出: {'Alice', 'Bob', 'Charlie'}
# 或者从字典的值创建集合
score_set = {score for score in student_scores.values()}
# 输出: {85, 90, 92}
# 创建一个集合,其中包含两个列表中所有可能的数对和(作为元组)
list1 = [1, 2, 3]
list2 = [4, 5, 6]
pairs_sum = {(x, y) for x in list1 for y in list2 if x + y > 5}
# 输出: {(1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)}
# 注意:这里我们生成的是元组,因为元组是不可变的,所以可以作为集合的成员。
# 使用多个变量
# 创建一个集合,其中包含元组中的第二个元素,但只包含偶数
points = [(1, 2), (3, 4), (5, 6)]
even_y_set = {y for x, y in points if y % 2 == 0}
# 输出: {2, 4, 6}
注意事项
- 集合推导式会生成一个新的集合对象,而不会修改现有的集合。
- 集合中的元素必须是唯一的,因此任何重复的元素都会被自动去除。
- 集合推导式通常比使用循环和条件语句来创建集合更简洁、更易读。
- 集合推导式生成的是不可变集合,因此不能包含可变对象(如列表、字典等)作为元素。如果尝试这样做,会引发
TypeError
。