为了账号安全,请及时绑定邮箱和手机立即绑定

“清单理解”是什么意思?它是如何工作的,我如何使用它?

“清单理解”是什么意思?它是如何工作的,我如何使用它?

蝴蝶不菲 2019-05-31 17:20:54
“清单理解”是什么意思?它是如何工作的,我如何使用它?我有以下代码:[x**2 for x in range(10)]当我在PythonShell中运行它时,它会返回:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]我已经搜索过了,这似乎被称为列表理解,但它是如何工作的呢?
查看完整描述

4 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超14个赞

从…文献:

列表理解为创建列表提供了一种简洁的方法。常见的应用程序是创建新的列表,其中每个元素是应用于另一个序列或可迭代的每个成员的某些操作的结果,或者创建满足特定条件的元素的子序列。


关于您的问题,列表理解功能与以下“普通”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]

诸若此类。


您也可以使用ifif...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 ...xrange(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施予123456.

警告:你总是需要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}

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中的生成器.


查看完整回答
反对 回复 2019-05-31
?
MMTTMM

TA贡献1869条经验 获得超4个赞

有列表、字典和集合理解,但没有元组理解(尽管要探索“生成器表达式”)。

它们解决的问题是Python中的传统循环是语句(不返回任何东西),而不是返回值的表达式。

它们不是每个问题的解决方案,可以重写为传统的循环。当需要在迭代之间维护和更新状态时,它们会变得很尴尬。

它们通常包括:

[<output expr> <loop expr <input expr>> <optional predicate expr>]

但会以很多有趣和奇怪的方式扭曲。

它们可以类似于传统的map()filter()在Python中仍然存在并继续使用的操作。

如果做得好,他们就有很高的满足率。


查看完整回答
反对 回复 2019-05-31
?
绝地无双

TA贡献1946条经验 获得超4个赞

如果你更喜欢用一种更直观的方式来了解正在发生的事情,那么也许这会有所帮助:


# for the example in the question...


y = []

for x in range(10):

    y += [x**2]


# is equivalent to...


y = [x**2 for x in range(10)]


# for a slightly more complex example, it is useful

# to visualize  where the various x's end up...


a = [1,2,3,4]

b = [3,4,5,6]

c = []


for x in a:

          if x in b:

                  c += [x]

#   \         \        /

#    \    _____\______/

#     \  /      \

#      \/        \

#      /\         \

#     /  \         \

#    /    \         \

c = [x for x in a if x in b]


print(c)

.产生输出[3, 4]


查看完整回答
反对 回复 2019-05-31
?
哔哔one

TA贡献1854条经验 获得超8个赞

最近,我看到很多关于列表理解是如何工作的困惑(在其他问题上和同事的问题上)。一点数学教育就能帮上忙为什么语法是这样的,列表理解真正意味着什么。

语法

最好把列表理解看作集合/集合上的谓词,就像我们在数学中使用集合生成器符号一样。这个表示法对我来说是很自然的,因为我拥有数学学士学位。但忘了我吧,GuidovanRossum(Python的发明者)拥有数学硕士学位,并且有数学背景。

设置建造者符号速成课程

以下是SET构建器表示法的(非常基本的)操作:

https://img1.sycdn.imooc.com//5cf0f23300016d3403700107.jpg

因此,这个集合构造符号表示严格正的一组数字(即[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构建符号,那么它们就更容易接受了。

哈!


查看完整回答
反对 回复 2019-05-31
  • 4 回答
  • 0 关注
  • 757 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信