我有一个包含多个属性的对象列表。我想根据对象的一个属性(country_code)过滤列表,即
当前列表
elems = [{'region_code': 'EUD', 'country_code': 'ROM', 'country_desc': 'Romania', 'event_number': '6880'},
{'region_code': 'EUD', 'country_code': 'ROM', 'country_desc':'Romania', 'event_number': '3200'},
{'region_code': 'EUD', 'country_code': 'ROM', 'country_desc': 'Romania', 'event_number': '4000'},
{'region_code': 'EUD', 'country_code': 'SVN', 'country_desc': 'Slovenia', 'event_number': '6880'},
{'region_code': 'EUD', 'country_code': 'NLD', 'country_desc':'Netherlands', 'event_number': '6880'},
{'region_code': 'EUD', 'country_code': 'BEL', 'country_desc':'Belgium', 'event_number': '6880'}]
所需清单
elems = [{'region_code': 'EUD', 'country_code': 'ROM', 'country_desc': 'Romania', 'event_number': '6880'},
{'region_code': 'EUD', 'country_code': 'SVN', 'country_desc': 'Slovenia', 'event_number': '6880'},
{'region_code': 'EUD', 'country_code': 'NLD', 'country_desc': 'Netherlands', 'event_number': '6880'},
{'region_code': 'EUD', 'country_code': 'BEL', 'country_desc': 'Belgium', 'event_number': '6880'}]
我可以通过创建一个字典和一个for循环来实现这一点,但我觉得在python中使用filter()或reduce()函数有一种更简单的方法,我只是无法弄清楚如何。
任何人都可以使用内置的python函数简化下面的代码吗?性能是一个重要因素,因为实际数据将是实质性的。
工作代码:
unique = {}
for elem in elems:
if elem['country_code'] not in unique.keys():
unique[elem['country_code']] = elem
print(unique.values())
值得注意的是,我也尝试了下面的代码,但它的性能比当前的工作代码还差:
unique = []
for elem in elems:
if not any(u['country_code'] == elem['country_code'] for u in unique):
unique.append(elem)
答案 0 :(得分:3)
我认为你的第一种方法已经非常接近于最佳状态。字典查找很快(就像在set
中一样快)并且循环很容易理解,即使有点冗长(通过Python标准),但为了简洁起见,你不应该牺牲可读性。
但是,您可以使用setdefault
删除一行,并且您可能希望使用collections.OrderedDict()
,以便结果列表中的元素按其原始顺序排列。另请注意,在Python 3中,unique.values()
不是列表,而是dict上的视图。
unique = collections.OrderedDict()
for elem in elems:
unique.setdefault(elem["country_code"], elem)
如果您真的,确实想要使用reduce
,您可以使用空dict作为初始值设定项,然后使用d.setdefault(k,v) and d
设置值(如果不存在)并返回修改后的字典。
unique = reduce(lambda unique, elem: unique.setdefault(elem["country_code"], elem) and unique,
elems, collections.OrderedDict())
我只会使用循环。
答案 1 :(得分:2)
我认为你的方法很好。检查elem['country_code'] not in unique
而不是elem['country_code'] not in unique.keys()
会更好。
但是,这是另一种使用列表理解的方法:
visited = set()
res = [e for e in elems
if e['country_code'] not in visited
and not visited.add(e['country_code'])]
最后一点滥用not None == True
和list.add
返回None
的事实。