Python 列表解析中的嵌套循环

115 阅读4分钟

当在 Python 中使用列表解析进行嵌套循环时,容易出现疑惑,例如下面的代码:

huake_00152_.jpg

item = [x+y for x in 'cat' for y in 'pot']
print(item)

输出结果为:

['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']

疑惑的地方在于,当两个循环的对象长度不一致时,列表解析是如何处理的?代码中的 'cat''pot' 分别有3个和4个字符,那么循环是如何进行的呢?

解决方案

Python 中的列表解析其实是对嵌套循环的语法糖,因此要理解列表解析中的循环,先要理解嵌套循环的原理。

嵌套循环是指在一个循环体内包含另一个或多个循环,外部循环称为外层循环,内部循环称为内层循环。嵌套循环可以实现复杂的数据处理,例如对多维数组进行遍历。

在列表解析中,嵌套循环的语法是:

[expression for item in iterable1 for item in iterable2 ...]

其中,expression 是要构建的元素,iterable1iterable2 是要循环的序列。

列表解析中的循环顺序

在列表解析中,循环的顺序是由内到外,即先执行内层循环,再执行外层循环。

例如,下面的代码将生成一个包含所有3位数字的列表:

[x*100 + y*10 + z for x in range(1, 10) for y in range(0, 10) for z in range(0, 10)]

在这个代码中,内层循环是 for z in range(0, 10),它会依次生成数字0、1、2、...、9。中层循环是 for y in range(0, 10),它会依次生成数字0、1、2、...、9。外层循环是 for x in range(1, 10),它会依次生成数字1、2、3、...、9。

因此,最终生成的列表将包含所有3位数字,并且这些数字是按照从000到999的顺序排列的。

列表解析中的循环长度

当列表解析中的两个循环长度不一致时,较短的循环会重复执行,直到较长的循环执行完毕。

例如,下面的代码将生成一个包含所有由 'cat' 和 'pot' 中的字符组成的字符串的列表:

[x+y for x in 'cat' for y in 'pot']

在这个代码中,内层循环是 for y in 'pot',它会依次生成字符 'p'、'o' 和 't'。外层循环是 for x in 'cat',它会依次生成字符 'c'、'a' 和 't'。

虽然 'cat' 中只有3个字符,而 'pot' 中有4个字符,但内层循环会重复执行,直到外层循环执行完毕。因此,最终生成的列表将包含所有由 'cat' 和 'pot' 中的字符组成的字符串,包括 'cp'、'co'、'ct'、'ap'、'ao'、'at'、'tp'、'to' 和 'tt'。

列表解析中的循环中断

如果在列表解析中遇到 breakcontinue 语句,循环将立即中断或继续。

例如,下面的代码将生成一个包含所有小于5的3位数字的列表:

[x*100 + y*10 + z for x in range(1, 10) for y in range(0, 10) for z in range(0, 10) if x*100 + y*10 + z < 5]

在这个代码中,if x*100 + y*10 + z < 5 是一个条件语句,如果 x*100 + y*10 + z 小于5,则该元素将被添加到列表中,否则将被忽略。

因此,最终生成的列表将包含所有小于5的3位数字,包括100、101、102、103、104、110、111、112、113、114、120、121、122、123、124、130、131、132、133、134、140、141、142、143、144、200、201、202、203、204、210、211、212、213、214、220、221、222、223、224、230、231、232、233、234、300、301、302、303、304、310、311、312、313、314、320、321、322、323、324、330、331、332、333、334、400、401、402、403、404。