Python仅使用列表理解动态计算没有重复项的列表
这是一个荒谬而怪异的用例,但请容忍我,我有以下理解:Python仅使用列表理解动态计算没有重复项的列表,python,list-comprehension,Python,List Comprehension,这是一个荒谬而怪异的用例,但请容忍我,我有以下理解: "reading_types": [ { "name": rt.reading_type, "value": rt.reading_type_id, } for unit in item.units for rt in unit.reading_types ], 在后端api调用中。它工作得很好,只是最终结果几乎总是重复的。如何确保不返回任何副本 这实际上是在另一个列表理解中发
"reading_types": [
{
"name": rt.reading_type,
"value": rt.reading_type_id,
}
for unit in item.units
for rt in unit.reading_types
],
在后端api调用中。它工作得很好,只是最终结果几乎总是重复的。如何确保不返回任何副本
这实际上是在另一个列表理解中发生的,我不能在任何时候引用列表来删除重复项,所以我必须在列表理解本身中这样做
我已尝试使用集
:
set([
{
"name": rt.reading_type,
"value": rt.reading_type_id,
}
for unit in item.units
for rt in unit.reading_types
])
但这会导致错误:
不可损坏类型:dict
您可以用另一种理解方式将整个列表包装到repr
每个条目中,并对其使用set
:
set([repr(val) for val in [...]])
这样做的目的是在不破坏结构的情况下使其可散列,这样您就可以恢复它们原来的状态 您可以将字典转换为
dict_items
,然后转换为tuples
(现在我们可以将其放入集合中,因为数据是可散列的),在其上应用集合,然后转换回字典:
input_list = [{"name":"name1","id":"id1"},{"name":"name2","id":"id2"},
{"name":"name1","id":"id1"}]
output_list = [dict(items) for items in {tuple(a.items()) for a in input_list}]
这是因为子目录的值是可散列的(字符串)。如果它们是字典,我们也得把它们转换成字典
结果:
[{'id': 'id1', 'name': 'name1'}, {'id': 'id2', 'name': 'name2'}]
另一种解决方案(由Jon Clements提出),它不使用集合
,而是构建一个字典(使用字典理解)&使用key unicity来删除重复项,然后只提取值:
list({tuple(d.items()):d for d in input_list}.values())
您可以在集合中使用而不是词典。作为不可变对象,namedtuple
s是可散列的,而字典不是。您也可以直接使用集合理解:
from collections import namedtuple
reading_type = namedtuple("reading_type", ["name", "value"])
{reading_type(rt.reading_type, rt.reading_type_id)
for unit in item.units
for rt in unit.reading_types}
这不是列表理解,但您可以使用第三方库中提供的itertools
,例如:
诀窍是确保您可以散列您的字典,我们通过将每个字典转换为一个已排序元组的元组来执行散列。在内部,该算法的工作原理是维护一个“seen”的值集,只生成不出现在集中的值,否则就添加它们。edit:实际上这并不好,因为repr
似乎只返回字符串化的对象,我不希望Python3.6有一个新的(更好)命名元组的语法,即使旧元组仍然有效。哇,这太棒了!我有一百万个问题,不太熟悉python,为什么是元组?为什么要用括号括起来?用冒号表示d的:d是什么语法?如果你能进一步解释这些,我将不胜感激!
from more_itertools import unique_everseen
input_list = [{"name":"name1","id":"id1"},{"name":"name2","id":"id2"},
{"name":"name1","id":"id1"}]
res = list(unique_everseen(input_list, key=lambda d: tuple(sorted(d.items()))))
print(res)
[{'name': 'name1', 'id': 'id1'}, {'name': 'name2', 'id': 'id2'}]