python的列表生成式
列表生成式是一种基于其他iterable(如集合、元组、其他列表等)创建列表的方法。它还可以用更简单、更吸引人的语法表示for和if循环。不过,列表生成式比for循环要快得多。
列表生成式的基本结构如下:
这看起来很简单,但在某些情况下可能会变得棘手。在本文中,我们将从一个非常简单的列表生成式开始,并逐步增加复杂性。我将清楚地解释如何表示和生成式高度复杂的列表生成式。
在大多数情况下,列表生成式优先于for和if循环,因为:
- 它们比for循环快得多
- 它们被认为比循环和映射函数更具python特性
- 列表生成式的语法更容易阅读
我们从一个简单的例子开始。
words = ['data','science','machine','learning']
我们要创建一个列表,其中包含单词列表中每个单词的长度。我们使用for循环和列表生成式来执行任务。
# for循环
a = []
for word in words:
a.append(len(word))
# 列表生成式
b = [len(word) for word in words]
print(f"a is {a}")
print(f"b is {b}")
a is [4, 7, 7, 8]
b is [4, 7, 7, 8]
生成式列表语法的最佳方法是比较for和if循环。下图演示了比较:
for循环末尾的表达式放在列表的开头。
当我们复习这些例子时,会更清楚。让我们创建一个列表,其中包含单词列表中长度大于5的项。
# for循环
a = []
for word in words:
if len(word) > 5:
a.append(word)
# 列表生成式
b = [word for word in words if len(word) > 5]
print(f"a is {a}")
print(f"b is {b}")
a is ['science', 'machine', 'learning']
b is ['science', 'machine', 'learning']
下图显示了如何在列表中表示循环中的表达式。
与上一个示例一样,在for循环末尾所做的事情被放在列表的开头。在这种情况下,我们按原样处理项。列表生成式的下一部分是循环中的第一个表达式,然后是循环中的第二个表达式。
循环中的逻辑更直观。因此,与循环相比,列表生成式的结构相对容易掌握。过一段时间,你就不必做一个明确的比较,因为你的大脑已经习惯了。
下一个例子稍微复杂一些。我们要创建一个包含单词列表项中所有“a”、“e”和“i”字母的列表。此任务涉及嵌套的for和if循环。
# for循环
a = []
for word in words:
for letter in word:
if letter in ["a","e","i"]:
a.append(letter)
详细说明一下语法:反复浏览单词表。对于每个项,遍历字符。如果一个字符符合给定的条件,它将被附加到列表a中。
完成相同任务的列表生成式如下。
b = [letter for word in words for letter in word if letter in ["a","e","i"]]
我们从for循环中的最后一个表达式开始生成式列表。剩下的部分从循环的开头开始。下图说明了每个步骤。
结论
列表生成式是一种高效的操作。对于简单的任务,生成式的语法很容易,在复杂的情况下可能会变得棘手。
如果你很难创建或生成式复杂的列表生成式,请尝试使用循环编写。
需要注意的是,列表生成式并不总是最佳选择。它们将整个输出列表加载到内存中。这对于中小型列表是可以接受的,甚至是可取的,因为它使操作更快。
然而,当我们处理大型列表(例如10亿个元素)时,应该避免列表生成式。它可能会导致你的计算机崩溃,由于内存需求量过大。
对于这样大的列表,一个更好的选择是使用一个生成器,它实际上不会在内存中创建一个大的数据结构。生成器在使用项时创建它们。用完后,生成器会将它们扔掉。生成器不会导致内存问题,但它们比列表生成式相对较慢。
转载自https://www.zhihu.com/people/panchuangai