题
他是个有趣的问题,看起来最Python的解决方案。假设我有一个映射列表 {'id': id, 'url': url}
.一些 id
s在列表中被重复,我希望创建一个新的名单,所有的重复删除。我想出了下列功能:
def unique_mapping(map):
d = {}
for res in map:
d[res['id']] = res['url']
return [{'id': id, 'url': d[id]} for id in d]
我想这是很有效的。但是有一个"多功能已大大增强"的方式?或也许是一个更有效的方式?
解决方案
你的例子能够改写略建造的第一个字使用发电机的表达,并消除有必要建设另一映射。只是再利用的旧的:
def unique_mapping(mappings):
return dict((m['id'], m) for m in mappings).values()
虽然这个出来作为一个衬垫,我仍然认为这是相当的可读性。
有两件事你必须记住,当使用原始方案和矿:
- 该项目将并不总是返回,在同样的顺序,他们最初
- 后来的条目将复盖前一项具有相同的id
如果你不介意的,那么我建议的解决方案上。在其他情况下,这种功能的保留以及对待第一个遇到的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))
如果你需要一个列表并不是一个发生器。
其他提示
有几件事情你可以改进。
你在执行两个循环,一种超过原来的字典,然后再一次在导致词典。你可以建立起自己的结果中的一个步骤,而不是。
你可以改变使用发电机,以避免建设的整体名单最前面。(使用名单(unique_mapping(项目))转换成一个完整的列表,如果你需要它)
有没有需要储存的价值时,只是检查重复的,可以使用一套替代。
你在重新创建一个典的每一个元素,而不是返回原来的。这实际上可能是需要(例如。你在修改它们,不要触摸的原始),但如果不是,它更有效地使用该词典已经建立。
这里有一个执行情况:
def unique_mapping(items):
s = set()
for res in items:
if res['id'] not in s:
yield res
s.add(res['id'])
我认为这可以更简单。字典不允许重复键。将映射列表放入映射字典中。这将删除重复项。
>>> 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'}]
不隶属于 StackOverflow