了解Python 3中的列表解析

介绍

列表推导提供了一种基于现有列表创建列表的简洁方法。 当使用列表推导时,列表可以通过利用任何可迭代的 ,包括字符串元组来构建。 在语法上,列表推导由包含表达式后跟一个for子句的iterable组成。 这可以跟着额外的forif子句,所以熟悉for循环条件语句将有助于更好地理解列表推导。 列表推导提供了创建列表和其他顺序数据类型的替代语法。虽然其他迭代方法(例如for循环)也可用于创建列表,但列表推导可能是首选,因为它们可以限制程序中使用的行数。

列表解析

在Python中,列表推导构造如下:
list_variable = [x for x in iterable]
列表或其他可迭代的,分配给一个变量。代表iterable中的项的其他变量是围绕for子句构造的。 in关键字用于在for循环中,以遍历iterable 。 让我们来看一个基于字符串创建列表的示例:
shark_letters = [letter for letter in 'shark']
print(shark_letters)
这里,新列表被分配给变量shark_letters ,而letter用于代表包含在可迭代字符串'shark' 。 为了让我们确认新列表shark_letters样子,我们调用print()并接收以下输出:
['s', 'h', 'a', 'r', 'k']
我们使用列表解析创建的列表由字符串'shark'中的项组成,即每个字母一个字符串。 列表推导可以重写为for循环,虽然不是每个for循环都能够被重写为列表推导。 使用我们的列表解析创建了上面的shark_letters列表,让我们将它重写为一个for循环。这可以帮助我们更好地了解列表解析的工作原理。
shark_letters = []

for letter in 'shark':
    shark_letters.append(letter)

print(shark_letters)
当使用for循环创建列表时,分配给列表的变量需要使用空列表初始化,因为它在我们的代码块的第一行。 for循环然后使用可迭代字符串'shark'中的变量letter来遍历项。 在for循环中,字符串中的每个项目都通过list.append(x)方法添加到列表中 。 将列表推导式重写为for循环为我们提供了相同的输出:
['s', 'h', 'a', 'r', 'k']
列表推导可以重写for循环,一些循环可以重写为列表推导,使代码更简洁。

使用条件与列表合算

列表推导可以在创建新列表时使用条件语句来修改现有列表或其他顺序数据类型。 让我们看一个在列表推导中使用的if语句的例子:
fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus')

fish_list = [fish for fish in fish_tuple if fish != 'octopus']
print(fish_list)
列表推导使用元组fish_tuple作为名为fish_list的新列表的基础。 使用forin的关键字,就像上面部分一样 ,现在添加了一个if语句。 if语句声明只添加那些不等同于字符串'octopus' ,所以新的列表只接受来自不与'octopus'匹配的元组的项目。 当我们运行这个,我们将看到fish_list包含与fish_list相同的字符串项,除了字符串'octopus'已被省略的事实:
['blowfish', 'clownfish', 'catfish']
因此,我们的新列表具有原始元组的每个项目,除了被条件语句排除的字符串。 我们将创建另一个使用数学运算符 ,整数和range()序列类型的示例。
number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)
正在创建的列表number_list将使用0-9范围内的每个项目的平方值填充, 如果项目的值可被2整除。输出如下:
[0, 4, 16, 36, 64]
为了分解列表解析正在做的更多,让我们考虑如果我们只是x for x in range(10)调用x for x in range(10)来打印出来。我们的小程序和输出将如下所示:
number_list = [x for x in range(10)]
print(number_list)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
现在,让我们添加条件语句:
number_list = [x for x in range(10) if x % 2 == 0]
print(number_list)
[0, 2, 4, 6, 8]
if语句将最终列表中的项目限制为仅包括可被2整除的项目,省略所有奇数。 最后,我们可以添加运算符以使每个x平方:
number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)
因此,先前的列表[0, 2, 4, 6, 8] 0,2,4,6,8 [0, 2, 4, 6, 8]中的每个数字现在是平方的:
[0, 4, 16, 36, 64]
您还可以使用列表推导复制嵌套if语句:
number_list = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
print(number_list)
这里,列表解析首先检查数字x是否可被3整除,然后检查x是否可被5整除。如果x满足这两个要求,它将打印,输出是:
[0, 15, 30, 45, 60, 75, 90]
条件if语句可用于控制来自现有序列的哪些项目包括在创建新列表中。

列表理解中的嵌套循环

嵌套循环可用于在我们的程序中执行多次迭代。 这一次,我们将看一个现有的嵌套for循环结构,并努力实现列表解析。 我们的代码将创建一个新的列表,它迭代两个列表,并根据它们执行数学运算。这里是我们的嵌套for循环代码块:
my_list = []

for x in [20, 40, 60]:
    for y in [2, 4, 6]:
        my_list.append(x * y)

print(my_list)
当我们运行这个代码,我们收到以下输出:
[40, 80, 120, 80, 160, 240, 120, 240, 360]
此代码在每次迭代中将第一个列表中的项与第二个列表中的项相乘。 为了将其转换为列表解析,我们将把每行代码压缩成一行,从x * y开始。 这将是外部for循环,然后是内部for循环。 我们将在列表解析下面添加一个print()语句,以确认新列表与我们使用上面的嵌套for循环块创建的列表相匹配:
my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]
print(my_list)
[40, 80, 120, 80, 160, 240, 120, 240, 360]
我们的列表解析采用嵌套的for循环,并将它们平面化为一行代码,同时仍然创建完全相同的列表以分配给my_list变量。 列表推导为我们提供了一个简洁的列表方式,使我们能够将几行代码提炼成一行。然而,值得记住的是,我们的代码的可读性应该总是优先的,因此当列表解析行变得太长或难以处理时,最好将其分解为循环。

结论

列表推导允许我们将一个列表或其他序列转换为新的列表。它们提供了一个简洁的语法来完成这个任务,限制了我们的代码行。 列表推导遵循集合构建器符号或集合推导的数学形式,因此它们可能对于具有数学背景的程序员特别直观。 虽然列表推导可以使我们的代码更简洁,重要的是确保我们的最终代码尽可能可读,所以应避免非常长的单行代码,以确保我们的代码是用户友好的。

分享按钮