将 for 循环转换为列表理解会产生不正确的结果

student = [['benny', 12.09], ['harry', 40.03], ['jenny', 56.03], ['garry', 56.33]]

for items in student:

    for _ in range(len(items)):

        if items[1] not in allscores:

          allscores.append(items[1])

print allscores

上面代码的输出是


[12.09, 40.03, 56.03, 56.33]

正如预期的那样。


但是如果我将 2 个for循环转换为列表理解,


allscores = [items[1] for _ in range(len(items)) if items[1] not in allscores for items in student]

print allscores

我得到:


allscores = [items[1] for _ in range(len(items)) if items[1] not in allscores for items in student]

NameError: name 'items' is not defined

我的列表理解有什么问题?


叮当猫咪
浏览 121回答 1
1回答

长风秋雁

出现错误的原因是像这样的双重理解中的循环是按照与 for 循环相同的顺序编写的。特别是,a = []for y in z:    for x in y:        a.append(x)可以改写为a = [x for y in z for x in y]不作为a = [x for x in y for y in z]您可能想到的语法是用于嵌套理解:a = [[x for x in y] for y in z]但这会创建一个 2D 列表,这绝对不是您在这里想要的。现在要回答您的实际问题,让我们从items[1] for _ in range(len(items)). 您实际上是items[1]在为列表中的每个元素检查两次。可能已经尝试确保子列表有两个元素,但是当您显式索引 element 时您将其杀死1。现在你会认为你可以将你的理解截断为allscores = [items[1] for items in students if items[1] not in allscores]但你不能。请记住,在理解完成之前,allscores是未定义的。将其预初始化为空列表也无济于事,因为在理解完成之前它将保持为空。解决方案是使用set. 它比您每次尝试使用inin 中的运算符进行的线性查找要高效得多if items[1] not in allscores。它还可以与生成器表达式而不是列表推导式一起使用,以避免存储不必要的元素:allscores = set(items[1] for items in students)请注意缺少周围的方括号。如果您绝对需要列表,请执行allscores = list(set(items[1] for items in students))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python