我对以下问题有一个解决方法。该解决方法将是一个for循环,其中包含一个包含在输出中的测试,如下所示:
#!/usr/bin/env python
def rem_dup(dup_list):
reduced_list = []
for val in dup_list:
if val in reduced_list:
continue
else:
reduced_list.append(val)
return reduced_list
我问的是以下问题,因为我很想知道是否有列表理解解决方案。
鉴于以下数据:
reduced_vals = []
vals = [1, 2, 3, 3, 2, 2, 4, 5, 5, 0, 0]
为什么
reduced_vals = = [x for x in vals if x not in reduced_vals]
生成相同的列表?
>>> reduced_vals
[1, 2, 3, 3, 2, 2, 4, 5, 5, 0, 0]
我认为这与检查输出(reduced_vals
)作为列表赋值的一部分有关。我很好奇,但确切的原因。
谢谢。
答案 0 :(得分:6)
列表推导创建一个新列表,而reduced_vals
在评估列表推导期间始终指向空列表。
Python中赋值的语义是:评估右侧并将结果对象绑定到左侧的名称。对裸名称从不的赋值会改变任何对象。
顺便说一下,您应该使用set()
或collections.OrderedDict.fromkeys()
以有效的方式删除重复项(取决于您是否需要保留订单)。
答案 1 :(得分:4)
您正在测试一个空列表。
在将表达式赋值为reduced_vals
的新值之前,首先对该表达式进行全面计算,因此在计算完整列表表达式之前,该表达式将保持为空。
换句话说,表达式[x for x in vals if x not in reduced_vals]
是独立执行的。如果您以稍微修改的方式查看代码,它可能会有所帮助:
temp_var = [x for x in vals if x not in reduced_vals]
reduced_vals = temp_var
del temp_var
以上是直接将列表表达式的结果分配给reduced_vals
的道德等价物,但我更明确地将使用第二个变量分配结果。
答案 2 :(得分:4)
在这一行:[x for x in vals if x not in reduced_vals]
reduced_vals
中没有一个不的值,因为reduced_vals
是空列表[]
。换句话说,没有任何内容被过滤,vals
中的所有元素都会被返回。
如果您尝试这样做:
[x for x in vals if x in reduced_vals]
结果是空列表[]
,因为 all {em}中的值不是(它是空的)。我相信你对列表理解中过滤部分的工作方式感到困惑:你看,过滤器只选择那些使条件成为reduced_vals
的值,但它不会阻止重复值。
现在,如果你需要的是过滤掉重复项,那么列表理解就不适合这项工作。为此,使用一个集合 - 虽然它不一定会保留原始列表的顺序,但它将保证元素是唯一的:
True
答案 3 :(得分:1)
因为在构建整个列表之前,列表推导中的元素未分配给reduced_vals
。如果您想使其工作,请使用for
循环.append()
。
答案 4 :(得分:0)
因为在评估列表理解期间reduced_vals
没有改变。