他是一个寻找最恐怖的解决方案的有趣问题。假设我有一个映射列表{'id': id, 'url': url}
。列表中的一些id
是重复的,我想创建一个新列表,删除所有重复项。我提出了以下功能:
def unique_mapping(map):
d = {}
for res in map:
d[res['id']] = res['url']
return [{'id': id, 'url': d[id]} for id in d]
我认为这很有效率。但是有更“Pythonic”的方式吗?或者也许是一种更有效的方式?
答案 0 :(得分:4)
您的示例可以稍微重写,以使用生成器表达式构造第一个字典,并删除构建其他映射的必要性。只需重复使用旧的:
def unique_mapping(mappings):
return dict((m['id'], m) for m in mappings).values()
虽然这是一个单行,但我仍然认为它很可读。
使用原始解决方案时我必须记住两件事:
如果您不介意,那么我建议上面的解决方案。在其他情况下,此函数保留顺序并以优先级处理首次遇到的ID:
def unique_mapping(mappings):
addedIds = set()
for m in mappings:
mId = m['id']
if mId not in addedIds:
addedIds.add(mId)
yield m
如果您需要列表而不是生成器,则可能需要使用list(unique_mappings(mappings))
来调用它。
答案 1 :(得分:2)
有几件事你可以改进。
你正在执行两个循环,一个在原始字典上,然后再在结果字典上。您可以一步建立结果。
您可以更改为使用生成器,以避免预先构建整个列表。 (如果需要,使用列表(unique_mapping(items))转换为完整列表)
在检查重复项时无需存储该值,您可以改用一组。
您正在为每个元素重新创建字典,而不是返回原始字典。实际上可能需要这样做(例如,您正在修改它们,并且不想触摸原始文件),但如果没有,则使用已创建的词典会更有效。
这是一个实现:
def unique_mapping(items):
s = set()
for res in items:
if res['id'] not in s:
yield res
s.add(res['id'])
答案 2 :(得分:1)
我认为这可以更简单。字典不允许重复键。将映射列表放入映射字典中。这将删除重复项。
>>> someListOfDicts= [
{'url': 'http://a', 'id': 'a'},
{'url': 'http://b', 'id': 'b'},
{'url': 'http://c', 'id': 'a'}]
>>> dict( [(x['id'],x) for x in someListOfDicts ] ).values()
[{'url': 'http://c', 'id': 'a'}, {'url': 'http://b', 'id': 'b'}]