Python 列表推导式详解

360影视 欧美动漫 2025-05-07 15:09 2

摘要:Python 的列表推导使开发人员能够以比传统方法更易读、更简洁、更高效的方式创建列表。通过使用列表推导式,开发人员可以减小代码大小,使其更易于维护和可读。同时,列表推导式通常优于使用传统循环编写的等效代码,从而提供了效率优势。

Python 的列表推导使开发人员能够以比传统方法更易读、更简洁、更高效的方式创建列表。通过使用列表推导式,开发人员可以减小代码大小,使其更易于维护和可读。同时,列表推导式通常优于使用传统循环编写的等效代码,从而提供了效率优势。

[expression for item in iterable if condition]expression:这是确定新列表中的值的输出表达式。它应用于满足条件的每个项目(如果指定)。表达式可以是项的简单转换,也可以是涉及项的更复杂的操作。iterable:这是遍历可迭代对象中每个项的循环。是一个 item 变量,它采用可迭代对象中每个连续项的值。condition(可选):这是一个条件语句,用于从可迭代对象中筛选项。只有条件计算结果为 True 的项目才会包含在新列表中。如果未指定条件,则使用可迭代对象中的所有项。squares = [x**2 for x in range(10) if x % 2 == 0]

1. x**2 是每个数字的平方表达式,

2. for x in range(10) 是数字 0 到 9 的迭代,并且

3. if x % 2 == 0 是只允许偶数平方的条件。

squares = [x**2 for x in range(1, 11)]

等效的 For 循环:

squares = for x in range(1, 11): squares.append(x**2)在此示例中,生成数字 1 到 10 的平方列表。列表推导比 for 循环版本短得多,可读性也强。

列表推导:

evens = [x for x in range(1, 11) if x % 2 == 0]

等效的 For 循环:

evens = for x in range(1, 11): if x % 2 == 0: evens.append(x)

列表推导:

words = ["Hello", "World", "In", "Python"]lowercase_words = [word.lower for word in words]

等效的 For 循环:

words = ["Hello", "World", "In", "Python"]lowercase_words = for word in words: lowercase_words.append(word.lower)将单词列表转换为小写。列表推导允许我们在一行易于理解的代码中执行此操作。numbers = [1, 2, 3, 4, 5, 6]evens = [num for num in numbers if num % 2 == 0]strings = ["hello", "", "world", "", "in", "", "python"]non_empty = [s for s in strings if s]

列表推导式循环访问列表中 strings 的每个字符串,并且仅当它为非空(即 if s )时才将其包含在新列表中 non_empty (即 )。在 Python 中,空字符串的计算结果在布尔上下文中, False 因此 if sTrue 仅适用于非空字符串。

numbers = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]positives = [num for num in numbers if num > 0]

如果想根据某些条件对项目应用不同的转换?这就是 if-else 条件的用武之地。通过在列表推导的输出表达式中包含条件 if-else ,我们可以为不同的项目生成不同的输出。

语法如下:

[expression_if_true if condition else expression_if_false for item in iterable]列表推导循环访问可迭代对象中的每个项目。对于每个项目,它都会检查状况。如果条件为 True ,则它包含在 expression_if_true 新列表中。如果条件为 False ,则它包含在 expression_if_false 新列表中。numbers = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]non_negatives = [num if num >= 0 else 0 for num in numbers]strings = ["Hello", "World", "In", "Python"]converted = [s.upper if s[0].isupper else s.lower for s in strings]列表推导循环访问列表中 strings 的每个字符串。如果字符串以大写字母开头,则会将整个字符串转换为大写,并将其包含在新列表中 converted 。如果字符串以小写字母开头,则会将整个字符串转换为小写,并将其包含在新列表中。numbers = [1, 2, 3, 4, 5, 6]classification = ["even" if num % 2 == 0 else "odd" for num in numbers]#['odd', 'even', 'odd', 'even', 'odd', 'even']列表推导遍历列表中 numbers 的每个数字。如果数字为偶数,则在新列表中 classification 包含字符串“偶数”。如果数字为奇数,则在新列表中包含字符串“奇数”。

从本质上讲,嵌套列表推导是列表推导中的列表推导。

语法:

[[expression for item in inner_iterable] for outer_item in outer_iterable]

在此语法中,外部列表推导遍历 outer_iterable ,对于每个 outer_item ,它使用内部列表推导生成一个新列表。内部列表推导会循环访问 inner_iterable 并应用于 expression 每个 item .

嵌套列表推导:

matrix = [[i for i in range(5)] for _ in range(5)]

等效传统代码:

matrix = for _ in range(5): row = for i in range(5): row.append(i) matrix.append(row)

嵌套列表推导式创建一个 5x5 矩阵,其中每行都是从 0 到 4 的数字列表。

嵌套列表推导:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]transpose = [[row[i] for row in matrix] for i in range(3)]

等效传统代码:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]transpose = for i in range(3): row = for row in matrix: row.append(row[i]) transpose.append(row)

嵌套列表推导转置了一个 3x3 矩阵,即它将行转换为列,反之亦然。

实际上,您可以将多个 for 循环合并到列表推导式中,以遍历多个可迭代对象或创建嵌套循环。当您需要展平嵌套列表或需要以某种方式组合多个列表的元素时,这可能特别有用。

语法:

[expression for item1 in iterable1 for item2 in iterable2]列表推导首先遍历 iterable1 。对于 中的 iterable1 每个 item1 ,然后它遍历 iterable2 。对于 中的每个 item2 它适用于 expression 新列表中的结果 item1 ,并 item2 包含 iterable2 结果。

具有多个 For 循环的列表推导:

nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]flattened = [num for sublist in nested_list for num in sublist]

等效传统代码:

nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]flattened = for sublist in nested_list: for num in sublist: flattened.append(num)

具有多个 for 循环的列表推导将嵌套列表展平为单个列表。

list1 = ['a', 'b', 'c']list2 = [1, 2, 3]product = [(letter, num) for letter in list1 for num in list2]

等效传统代码:

list1 = ['a', 'b', 'c']list2 = [1, 2, 3]product = for letter in list1: for num in list2: product.append((letter, num))

具有多个 for 循环的列表推导生成两个列表的笛卡尔乘积,即它将第一个列表的每个元素与第二个列表的每个元素配对。

通过将函数和方法调用合并到列表推导式中,可以对数据执行各种操作。

语法:

[function(item) for item in iterable]

使用函数调用进行列表推导:

def square(x): return x ** 2numbers = [1, 2, 3, 4, 5]squares = [square(num) for num in numbers]

等效传统代码:

def square(x): return x ** 2numbers = [1, 2, 3, 4, 5]squares = for num in numbers: squares.append(square(num))

列表推导将函数 square 应用于列表中 numbers 的每个数字。

使用方法调用进行列表推导:

strings = ["hello", "world", "in", "python"]uppers = [s.upper for s in strings]

等效传统代码:

strings = ["hello", "world", "in", "python"]uppers = for s in strings: uppers.append(s.upper)

在此示例中,列表推导式对列表中 strings 的每个字符串调用该 upper 方法。

您可以使用类似的语法为其他数据结构(包括字典、集合和元组)创建推导式。

字典理解:

words = ["hello", "world", "in", "python"]word_lengths = {word: len(word) for word in words}

等效传统代码:

words = ["hello", "world", "in", "python"]word_lengths = {}for word in words: word_lengths[word] = len(word)

设置理解:

numbers = [1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5]unique_squares = {num**2 for num in numbers}

等效传统代码:

numbers = [1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5]unique_squares = setfor num in numbers: unique_squares.add(num**2)

集合推导式创建一个新集合,其中每个元素都是列表中 numbers 一个数字的平方。由于集合会自动删除重复项,因此生成的集合仅包含唯一方块。

对于需要大量数据或一次不需要整个列表的操作,生成器表达式可能是更有效的替代方法。生成器表达式类似于列表推导式,但它不是创建列表,而是创建生成器对象。生成器是动态生成其元素的迭代器,可以在处理大量数据时节省内存。语法:(expression for item in iterable)

列表推导式和生成器表达式的语法之间的唯一区别是使用的括号类型。

生成器表达式:

numbers = range(1, 1000001)sum_of_squares = sum(num**2 for num in numbers)

等效列表理解:

numbers = range(1, 1000001)sum_of_squares = sum([num**2 for num in numbers])

在此示例中,生成器表达式和列表推导式都计算从 1 到 1,000,000 的数字的平方和。但是,生成器表达式无需创建所有 100 万个方块的列表即可执行此操作,从而节省了大量内存。

生成器表达式:

words = ["apple", "banana", "cherry", "date", "elderberry"]first_long_word = next(word for word in words if len(word) > 5)

等效列表理解:

words = ["apple", "banana", "cherry", "date", "elderberry"]first_long_word = next(word for word in [word for word in words if len(word) > 5])在此示例中,生成器表达式和列表推导式都查找列表中 words 长度超过 5 个字符的第一个单词。但是,生成器表达式在找到匹配的单词后立即停止,而列表推导式在找到第一个单词之前创建所有匹配单词的列表。性能注意事项:额外内存:

列表推导式会在内存中创建一个新列表,这可能会占用大量内存来处理大型数据集。相比之下,传统循环通常可以就地修改列表,从而避免了对额外内存的需求。

列表推导:

等效传统代码:

numbers = range(1, 1000001)sum_of_squares = 0for num in numbers: sum_of_squares += num**2在此示例中,列表推导式和传统循环都计算从 1 到 1,000,000 的数字的平方和。但是,列表推导会创建一个包含所有 100 万个方块的列表,消耗大量内存,而传统循环会动态计算每个方块并将其添加到总和中,使用更少的内存。

使用列表推导式:

numbers = list(range(1, 21))filtered_numbers = [n for n in numbers if n % 2 == 0 and n % 5 == 0]

没有列表推导式:

numbers = list(range(1, 21))filtered_numbers = for n in numbers: if n % 2 == 0 and n % 5 == 0: filtered_numbers.append(n)此代码从列表“数字”中过滤偶数且能被 5 整除的数字。列表推导版本更简洁地做到这一点。

使用列表推导式:

numbers = [1, 2, 3, 4, 5]complex_expressions = [(n**2 + 10) / 5 for n in numbers]

没有列表推导式:

numbers = [1, 2, 3, 4, 5]complex_expressions = for n in numbers: complex_expressions.append((n**2 + 10) / 5)

使用列表推导式:

names = ['Alice', 'Bob', 'Charlie', 'Dave']greetings = ['Hello, ' + name + '!' for name in names]

没有列表推导式:

names = ['Alice', 'Bob', 'Charlie', 'Dave']greetings = for name in names: greetings.append('Hello, ' + name + '!')此代码在每个名称的开头附加“Hello, ”,在末尾附加“!”。

使用列表推导式:

names = ['Alice', 'Bob', 'Charlie', 'Dave']indexed_names = [(i, name) for i, name in enumerate(names)]

没有列表推导式:

names = ['Alice', 'Bob', 'Charlie', 'Dave']indexed_names = for i, name in enumerate(names): indexed_names.append((i, name))

此代码将每个名称与其在列表中的索引配对。

没有列表推导式:

pairs = [(1, 'one'), (2, 'two'), (3, 'three')]numbers = for num, name in pairs: numbers.append(num)

使用列表推导式:

pairs = [(1, 'one'), (2, 'two'), (3, 'three')]numbers = [num for num, name in pairs]

此代码提取列表中每个元组的第一个元素。

没有列表推导式:

list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]first_elements = for sublist in list_of_lists: first_elements.append(sublist[0])

使用列表推导式:

list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]first_elements = [sublist[0] for sublist in list_of_lists]

此代码从每个子列表中提取第一个元素。

没有列表推导式:

words = ['apple', 'banana', 'cherry', 'date', 'elderberry']short_words = for word in words: if len(word)

使用列表推导式:

words = ['apple', 'banana', 'cherry', 'date', 'elderberry']short_words = [word for word in words if len(word) 此代码创建具有 5 个或更少字母的单词列表。

没有列表推导式:

list1 = [1, 2, 3]list2 = [4, 5, 6]combined = for x, y in zip(list1, list2): combined.append((x, y))

使用列表推导式:

list1 = [1, 2, 3]list2 = [4, 5, 6]combined = [(x, y) for x, y in zip(list1, list2)]此代码创建一个元组列表,其中每个元组在相应索引处包含 list1 中的一个元素和 list2 中的一个元素。

没有列表理解:

numbers = [1, 2, 3, 4, 5]labels = for number in numbers: if number % 2 == 0: labels.append('even') else: labels.append('odd')

使用列表推导式:

numbers = [1, 2, 3, 4, 5]labels = ['even' if number % 2 == 0 else 'odd' for number in numbers]此代码将每个数字标记为“偶数”或“奇数”。

没有列表推导式:

words = ['apple', 'banana', 'cherry']indexed_words = for i, word in enumerate(words): indexed_words.append((i, word))

使用列表推导式:

words = ['apple', 'banana', 'cherry']indexed_words = [(i, word) for i, word in enumerate(words)]此代码将每个单词与其索引配对。

没有列表推导式:

products = for i in range(2, 5): for j in range(1, 10): products.append((i, j, i*j))

使用列表推导式:

products = [(i, j, i*j) for i in range(2, 5) for j in range(1, 10)]列表推导式使用两个 for 表达式在两个不同的范围内循环访问。在传统代码中,我们使用两个嵌套的 for 循环来生成元组。

没有列表推导式:

numbers = [1, 2, 3, 4, 5, 6]filtered_numbers = for num in numbers: if num % 2 == 0: if num % 3 == 0: filtered_numbers.append(num ** 2)

使用列表推导式:

numbers = [1, 2, 3, 4, 5, 6]filtered_numbers = [num ** 2 for num in numbers if num % 2 == 0 if num % 3 == 0]

没有列表推导式:

sentence = "The quick brown fox jumps over the lazy dog and the dog jumps over the fox"unique_words = for word in sentence.split: word = word.lower if word not in unique_words: unique_words.append(word)

通过列表推导式:

sentence = "The quick brown fox jumps over the lazy dog and the dog jumps over the fox"unique_words = list(set(word.lower for word in sentence.split))此代码片段从给定句子中创建唯一单词的列表,忽略大小写。

没有列表推导式:

list1 = [1, 2, 3, 4, 5, 6]list2 = [4, 5, 6, 7, 8, 9]list3 = [6, 7, 8, 9, 10, 11]common_elements = for x in list1: if x in list2 and x in list3: if x not in common_elements: common_elements.append(x)

使用列表理解:

list1 = [1, 2, 3, 4, 5, 6]list2 = [4, 5, 6, 7, 8, 9]list3 = [6, 7, 8, 9, 10, 11]common_elements = list(set(x for x in list1 if x in list2 and x in list3))创建质数列表

没有列表理解:

primes = for x in range(2, 50): is_prime = True for i in range(2, int(x**0.5) + 1): if x % i == 0: is_prime = False break if is_prime: primes.append(x)

通过列表推导:

primes = [x for x in range(2, 50) if all(x % i != 0 for i in range(2, int(x**0.5) + 1))]

没有列表理解:

vector1 = [1, 2, 3]vector2 = [4, 5, 6]dot_product = 0for x, y in zip(vector1, vector2): dot_product += x * y

使用列表理解:

vector1 = [1, 2, 3]vector2 = [4, 5, 6]dot_product = sum(x * y for x, y in zip(vector1, vector2))此代码片段使用列表推导计算两个列表(向量)的点积。

没有列表理解:

text = "hello world"char_freq = unique_chars = set(text)for char in unique_chars: if char != ' ': char_freq.append({char: text.count(char)})

使用列表理解:

text = "hello world"char_freq = [{char: text.count(char)} for char in set(text) if char != ' ']此代码片段创建一个字典列表,其中包含给定字符串中每个字符的频率,忽略空格。

没有列表理解:

result = for x in [10, 30, 50]: for y in [20, 40, 60]: if x + y > 50: result.append(x + y)

使用列表理解:

result = [x+y for x in [10, 30, 50] for y in [20, 40, 60] if x+y > 50]列表推导将两个 for 表达式和一个 if 条件组合在一行中,阅读和理解起来可能会令人困惑。传统代码将操作分解为单独的、更易于理解的步骤。

没有列表理解:

result = for x in range(-2, 4): if x > 2: result.append(x) elif x

使用列表理解:

result = [x if x > 2 else x * 2 if x 列表推导在一行中使用两个 if-else 条件,这可能难以阅读和理解,特别是因为列表推导中 if and else 语句的顺序不同。传统代码使用更易于阅读和理解的单独 if 、 elif 和 else 语句。# creating a list of squaressquares = [x**2 for x in range(10)]# combining the elements of two lists if they are not equalcombs = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]# creating a new list with the values doubleddoubled = [x*2 for x in [-4, -2, 0, 2, 4]]# filtering the list to exclude negative numbersnon_neg = [x for x in [-4, -2, 0, 2, 4] if x >= 0]# applying a function to all the elementsabs_values = [abs(x) for x in [-4, -2, 0, 2, 4]]# calling a method on each elementtrimmed = [s.strip for s in [' banana', ' loganberry ', 'passion fruit ']]# creating a list of 2-tuples like (number, square)squares = [(x, x**2) for x in range(6)]# flattening a list using a listcomp with two 'for'flat_list = [num for elem in [[1,2,3], [4,5,6], [7,8,9]] for num in elem]# using complex expressions and nested functionsfrom math import pirounded_pi = [str(round(pi, i)) for i in range(1, 6)]

来源:自由坦荡的湖泊AI一点号

相关推荐