我有一份名单
In [4]: a = [1, 2, 3, 3, 2, 4]我想通过使用哨兵列表(见下面的原因)通过理解删除重复的内容:
In [8]: [x if x not in seen else seen.append(x) for x in a]
Out[8]: [1, 2, 3, 3, 2, 4]看来seen没有被考虑在内(既没有更新,也没有检查)。为什么会这样呢?
至于使用复杂方法的原因:我所拥有的列表是形式的。
[{'a': 3, 'b': 4}, {'a': 10, 'b': 4}, {'a': 5, 'b': 5}]我希望根据特定键的值删除重复项(在上述情况下是b,以保留[{'a': 3, 'b': 4}, {'a': 5, 'b': 5}] (我不在乎删除哪个dict )。这样做的目的是构建一个带有b值的哨兵列表,并且只保留没有b的dicts与该哨兵列表中的任何元素相等。
发布于 2015-01-26 12:55:33
因为x不在seen中,所以您也不会将它添加到seen中;当x not in seen为true时,不会执行else分支。
但是,您使用的是条件表达式;它总是生成一个值;x或seen.append()的结果(即None),因此您不是在过滤,而是在这里映射。
如果要筛选,请将测试移到if循环之后的for部分:
seen = set()
[x for x in a if not (x in seen or seen.add(x))]由于您使用的是seen.append(),我猜想您使用的是一个列表;我将您改为set(),因为使用集合进行成员资格测试要快得多。
因此,只有在以下情况下,x才被排除在外:x in seen是真(因此我们已经看到了),或者seen.append(x)返回了真值(None不是真)。是的,如果有点复杂的话,这是可行的。
演示:
>>> a = [1, 2, 3, 3, 2, 4]
>>> seen = set()
>>> [x for x in a if not (x in seen or seen.add(x))]
[1, 2, 3, 4]
>>> seen
set([1, 2, 3, 4])将此应用于您的特定问题:
>>> a = [{'a': 3, 'b': 4}, {'a': 10, 'b': 4}, {'a': 5, 'b': 5}]
>>> seen = set()
>>> [entry for entry in a if not (entry['b'] in seen or seen.add(entry['b']))]
[{'a': 3, 'b': 4}, {'a': 5, 'b': 5}]发布于 2015-01-26 12:57:49
您从不执行if的else部分,因为在第一次匹配时不进行更新。你可以这样做:
[seen.append(x) or x for x in lst if x not in seen]这样,or返回最后一个值(并使用append执行更新(它总是返回None,以让或继续寻找真值-y值)。
也许您可以使用这样的事实,即dict键是用于此的集合。如果希望对最后一项进行优先级排序,请使用reversed (最后一项在这里被排序):
>>> lst = [{'a': 3, 'b': 4}, {'a': 10, 'b': 4}, {'a': 5, 'b': 5}]
>>> filtered = {item['b']: item for item in reversed(lst)}
>>> filtered.values()
[{'a': 3, 'b': 4}, {'a': 5, 'b': 5}]这使用'b'作为将值映射到的键,因此只能将单个元素映射到'b'‘值,这实际上在'b'上创建了一个集合。
注意:,这将以随机顺序返回值。为了很好地修复大数据集,我将创建另一个映射,将每个对象映射到原始列表(O(n))中的索引,并使用该映射作为最终结果(O(n*log(N)的排序函数。这超出了这个答案的范围。
发布于 2015-01-26 14:03:29
我总是不愿意使用操作符优先级作为执行流控制。我觉得下面的内容稍微更明确,更令人愉快,尽管它确实承担了元组创建的额外成本。
b_values = set()
[(item, b_values.add(item['b']))[0] for item in original_list
if item['b'] not in b_values]但实际上,当您维护/更新某种状态时,我认为最好的格式是简单的for-循环:
output_list = []
b_values = set()
for item in original_list:
if item['b'] not in b_values:
output_list.append(item)
b_values.add(item['b'])https://stackoverflow.com/questions/28150479
复制相似问题