翻翻过去那场雪
从…文献:列表理解为创建列表提供了一种简洁的方法。常见的应用程序是创建新的列表,其中每个元素是应用于另一个序列或可迭代的每个成员的某些操作的结果,或者创建满足特定条件的元素的子序列。关于您的问题,列表理解功能与以下“普通”Python代码相同:>>> l = [] >>> for x in range(10):... l.append(x**2)>>> l[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]你怎么把它写成一行?嗯.我们可以.也许.用map()带着lambda:>>> list(map(lambda x: x**2, range(10)))[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]但是,仅仅使用一个列表理解不是更清晰更简单吗?>>> [x**2 for x in range(10)][0, 1, 4, 9, 16, 25, 36, 49, 64, 81]基本上,我们可以做任何事x..不仅x**2..例如,运行x:>>> [x.strip() for x in ('foo\n', 'bar\n', 'baz\n')]['foo', 'bar', 'baz']或使用x作为另一个函数的论点:>>> [int(x) for x in ('1', '2', '3')][1, 2, 3]例如,我们也可以使用x作为一个dict对象。让我们看看:>>> d = {'foo': '10', 'bar': '20', 'baz': '30'}>>> [d[x] for x in ['foo', 'baz']]['10', '30']密码怎么样?>>> d = {'foo': '10', 'bar': '20', 'baz': '30'}>>> [int(d[x].rstrip('0')) for x in ['foo', 'baz']][1, 3]诸若此类。您也可以使用if或if...else在一个列表的理解中。例如,您只需要在range(10)..你可以:>>> l = []>>> for x in range(10):... if x%2:... l.append(x)>>> l[1, 3, 5, 7, 9]啊太复杂了。下面的版本呢?>>> [x for x in range(10) if x%2][1, 3, 5, 7, 9]使用if...else三元表达式,您需要将if ... else ...后x, 不后range(10):>>> [i if i%2 != 0 else None for i in range(10)][None, 1, None, 3, None, 5, None, 7, None, 9]你听说过吗嵌套列表理解?你可以把两个或更多for在一个列表中理解..例如:>>> [i for x in [[1, 2, 3], [4, 5, 6]] for i in x][1, 2, 3, 4, 5, 6]>>> [j for x in [[[1, 2], [3]], [[4, 5], [6]]] for i in x for j in i]
[1, 2, 3, 4, 5, 6]让我们谈谈第一部分,for x in [[1, 2, 3], [4, 5, 6]]这给了[1, 2, 3]和[4, 5, 6]..然后,for i in x施予1, 2, 3和4, 5, 6.警告:你总是需要for x in [[1, 2, 3], [4, 5, 6]] 以前 for i in x:>>> [j for j in x for x in [[1, 2, 3], [4, 5, 6]]]Traceback (most recent call last):
File "<input>", line 1, in <module>NameError: name 'x' is not defined我们也有集合理解, DECT理解,和生成器表达式.集合理解列表理解基本相同,但前者返回的是集而不是列单:>>> {x for x in [1, 1, 2, 3, 3, 1]}{1, 2, 3}这和:>>> set([i for i in [1, 1, 2, 3, 3, 1]]){1, 2, 3}A DECT理解 看上去一套理解,但它使用{key: value for key, value in ...}或{i: i for i in ...}而不是{i for i in ...}.例如:>>> {i: i**2 for i in range(5)}{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}它等于:>>> d = {}>>> for i in range(5):... d[i] = i**2>>> d{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}是吗?(i for i in range(5))给.元组?不!这是生成器表达式..返回发电机:>>> (i for i in range(5))<generator object <genexpr> at 0x7f52703fbca8>这和:>>> def gen():... for i in range(5):... yield i>>> gen()<generator object gen at 0x7f5270380db0>你可以用它作为生成器:>>> gen = (i for i in range(5))>>> next(gen)0>>> next(gen)1>>> list(gen)[2, 3, 4]>>> next(gen)Traceback (most recent call last):
File "<input>", line 1, in <module>StopIteration注:如果使用列表理解函数内部,你不需要[]如果这个函数可以在生成器上循环。例如,sum():>>> sum(i**2 for i in range(5))30相关(关于发电机):理解Python中的生成器.
哔哔one
最近,我看到很多关于列表理解是如何工作的困惑(在其他问题上和同事的问题上)。一点数学教育就能帮上忙为什么语法是这样的,列表理解真正意味着什么。语法最好把列表理解看作集合/集合上的谓词,就像我们在数学中使用集合生成器符号一样。这个表示法对我来说是很自然的,因为我拥有数学学士学位。但忘了我吧,GuidovanRossum(Python的发明者)拥有数学硕士学位,并且有数学背景。设置建造者符号速成课程以下是SET构建器表示法的(非常基本的)操作:因此,这个集合构造符号表示严格正的一组数字(即[1,2,3,4,...]).混淆点1) Set Builder表示法中的谓词筛选器只指定要保留哪些项,而列表理解谓词则做同样的事情。您不必包含省略项的特殊逻辑,除非谓词包含它们,否则它们将被省略。空谓词(即末尾没有条件)包括给定集合中的所有项。2) Set Builder表示法中的谓词过滤器位于末尾,在列表理解中也是如此。(有些)初学者认为[x < 5 for x in range(10)]会给他们名单[0,1,2,3,4],而实际上它输出了[True, True, True, True, True, False, False, False, False, False]..我们得到输出[True, True, True, True, True, False, False, False, False, False]因为我们让Python评估x < 5为全中的项目range(10)..没有谓词意味着我们从集合中获得一切(就像在SETBuilderNotation中那样)。如果在使用列表理解的同时在脑海中保留SET构建符号,那么它们就更容易接受了。哈!