介绍
List comprehensions offer a succinct way to create lists based on existing lists. When using list comprehensions, lists can be built by leveraging any iterable, including strings and tuples.
从语法上讲,列表理解是由包含一个表达式和一个for
条款的迭代组成的,可以随后添加额外的for
或if
条款,因此熟悉 **(for loops)(https://andsky.com/tech/tutorials/how-to-construct-for-loops-in-python-3)**和 **(https://andsky.com/tech/tutorials/how-to-write-conditional-statements-in-python-3-2)**将有助于您更好地理解列表理解。
列表理解为创建列表和其他序列 [数据类型] 的替代语法(https://andsky.com/tech/tutorials/understanding-data-types-in-python-3)。 虽然其他迭代方法,如为
循环,也可以用于创建列表,但列表理解可能更受欢迎,因为它们可以限制程序中使用的行数。
前提条件
如果您没有设置编程环境,您可以参考本地编程环境的安装和安装指南(https://www.digitalocean.com/community/tutorial_series/how-to-install-and-set-up-a-local-programming-environment-for-python-3)或适用于您的操作系统(Ubuntu, CentOS, Debian 等)的编程环境(https://www.digitalocean.com/community/tutorial_collections/how-to-install-python-3-and-set-up-a-programming-environment)。
清单理解
在Python中,列表理解是这样构建的:
<$>[info]
信息: 要跟进本教程中的示例代码,请在本地系统上运行python3
命令,打开Python交互壳。
1list_variable = [x for x in iterable]
一个列表或其他可重复性被分配给一个变量。在可重复性中代表项目的额外变量是围绕一个for
条款构建的。
让我们看看一个基于字符串创建列表的例子:
1shark_letters = [letter for letter in 'shark']
2print(shark_letters)
在这里,新列表被分配到变量 shark_letters
,而 letter
被用来代表可迭代字符串 shark
中包含的项目。
为了确认新列表shark_letters
的样子,我们要求它打印(),并收到以下输出:
1[secondary_label Output]
2['s', 'h', 'a', 'r', 'k']
我们用列表理解创建的列表由鲨鱼
字符串中的项目组成,即每个字母的一个字符串。
列表理解可以重写为for
循环,但不是每个for
循环都可以重写为列表理解。
使用我们创建的shark_letters
列表的列表理解,让我们将其重写为for
循环,这可能有助于我们更好地了解列表理解如何工作。
1shark_letters = []
2
3for letter in 'shark':
4 shark_letters.append(letter)
5
6print(shark_letters)
在创建具有for
循环的列表时,必须将分配给列表的变量初始化为空列表,因为它位于我们代码块的第一行中。
重写列表理解作为一个为
循环为我们提供了相同的输出:
1[secondary_label Output]
2['s', 'h', 'a', 'r', 'k']
列表理解可以重写为for
循环,一些for
循环可以重写为列表理解,以使代码更简洁。
使用有条件的列表理解
列表理解可以使用条件陈述来修改现有列表或创建新列表时的其他序列数据类型。
让我们看看在列表理解中使用的如果
语句的例子:
1fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus')
2
3fish_list = [fish for fish in fish_tuple if fish != 'octopus']
4print(fish_list)
列表理解使用tuple fish_tuple
作为名为 fish_list
的新列表的基础。 使用了 for
和 in
的关键字,就像在 上面的部分中一样,现在添加了 if
语句。
当我们执行此操作时,我们会注意到fish_list
包含与fish_tuple
相同的字符串项目,除非octopus
字符串被省略:
1[secondary_label Output]
2['blowfish', 'clownfish', 'catfish']
因此,我们的新列表包含原始字符串的每一个项目,除了被条件声明排除的字符串。
我们将创建另一个例子,使用数学运算符(https://andsky.com/tech/tutorials/how-to-do-math-in-python-3-with-operators),整数符(https://andsky.com/tech/tutorials/understanding-data-types-in-python-3#numbers),以及 range()
序列类型。
1number_list = [x ** 2 for x in range(10) if x % 2 == 0]
2print(number_list)
正在创建的列表 number_list
将填充从 0 到 9 之间的每个项目的平方值 如果 项目的值是可分为 2 的,则输出如下:
1[secondary_label Output]
2[0, 4, 16, 36, 64]
为了进一步分解列表理解正在做的事情,让我们想想如果我们只调用x为x在范围(10)
。
1number_list = [x for x in range(10)]
2print(number_list)
1[secondary_label Output]
2[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
现在,让我们添加条件声明:
1number_list = [x for x in range(10) if x % 2 == 0]
2print(number_list)
1[secondary_label Output]
2[0, 2, 4, 6, 8]
如果
语句限制了最终列表中的项目,仅包含可分为2的项目,忽略了所有偶数。
最后,我们可以添加运算符,以便每个x
的方块:
1number_list = [x ** 2 for x in range(10) if x % 2 == 0]
2print(number_list)
因此,以前列出的[0, 2, 4, 6, 8]
中的每一个数字现在都是方形的:
1[secondary_label Output]
2[0, 4, 16, 36, 64]
你也可以复制(https://andsky.com/tech/tutorials/how-to-write-conditional-statements-in-python-3-2#nested-if-statements)与清单理解:
1number_list = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
2print(number_list)
在这里,列表理解首先会检查如果数字x
是可分3的,然后检查是否x
是可分5的。
1[secondary_label Output]
2[0, 15, 30, 45, 60, 75, 90]
可以使用有条件的如果
语句来控制在创建新列表时包含现有序列中的哪些项目。
在一份清单中的嵌套环节理解
雀巢循环可用于在我们的程序中执行多个迭代。
这一次,我们将审查现有的嵌入式为
循环建设,并朝着清单理解的方向努力。
我们的代码将创建一个新的列表,重复2个列表并基于它们执行数学操作。
1my_list = []
2
3for x in [20, 40, 60]:
4 for y in [2, 4, 6]:
5 my_list.append(x * y)
6
7print(my_list)
当我们运行此代码时,我们会收到以下输出:
1[secondary_label Output]
2[40, 80, 120, 80, 160, 240, 120, 240, 360]
此代码是将第一列表中的项目乘以第二列表中的项目在每个迭代中。
要将此转化为列表理解,我们将将代码的每个行压缩为一个行,从x * y
操作开始。 接着是外部for
循环,然后是内部for
循环。
1my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]
2print(my_list)
1[secondary_label Output]
2[40, 80, 120, 80, 160, 240, 120, 240, 360]
我们的列表理解采用嵌入的for
循环,并将它们平板化为一个代码行,同时仍然创建相同的列表,以分配给my_list
变量。
清单理解为我们提供了简要的清单制作方式,使我们能够将几行代码蒸成一行,但是,值得记住,我们的代码的可读性应该始终优先,所以当一个清单理解的行变得太长或模糊时,最好把它打破成循环。
结论
列表理解允许我们将一个列表或其他序列转换为新列表,它们为完成这个任务提供了简要的语法,限制了我们的代码行。
列表理解遵循组建符号或组理解的数学形式,因此对于具有数学背景的程序员来说,它们可能特别直观。
虽然列表理解可以使我们的代码更简短,但重要的是确保我们的最终代码尽可能易读,所以应该避免非常长的单行代码,以确保我们的代码是用户友好的。