怎么把 list1 和 list2 中包含的重复字典去除,合并生成一个新的 list_all?

2016-12-16 11:42:27 +08:00
 rogwan

list1 = [{'name': 'Tom', 'score':90}, {'name': 'Jack', 'score':86}, {'name': 'Lisa', 'score':81}, {'name': 'Bill', 'score':70}]

list2 = [{'name': 'Jack', 'score':86}, {'name': 'Bill', 'score':70}, {'name': 'Bob', 'score':48}]

怎么把 list1 和 list2 去重合并到一个新的 list_all (保持 score 的顺序),把重合的部分拆分到一个新的 list_new:

list_all = [{'name': 'Tom', 'score':90}, {'name': 'Jack', 'score':86}, {'name': 'Lisa', 'score':81}, {'name': 'Bill', 'score':70}, {'name': 'Bob', 'score':48}]

list_new = [{'name': 'Jack', 'score':86}, {'name': 'Bill', 'score':70}]

4066 次点击
所在节点    Python
26 条回复
hareandlion
2016-12-16 12:07:38 +08:00
可以用 dict.update ,相同 key 的话新值会替换旧值
hareandlion
2016-12-16 12:10:56 +08:00
看错了不好意思,这种复杂结构只能手动遍历了吧
cxyfreedom
2016-12-16 12:15:18 +08:00
list_all = sorted(list1+list2, key=lambda x: x['score'], reverse=True)
list_new = [i for i in list1 if i in list2]
rogwan
2016-12-16 12:34:13 +08:00
@cxyfreedom 谢谢!你的 list_all 的方式不去重 ... 我在“去重”上的实现绕了好多圈,自己都看不过去了 *_*
xiaolajiao
2016-12-16 12:42:52 +08:00
去重这样: {v['name']:v for v in list1+list2}.values()
http://stackoverflow.com/questions/11092511/python-list-of-unique-dictionaries
weyou
2016-12-16 12:45:35 +08:00
list_all = sorted([dict(i) for i in set([tuple(d.items()) for d in list1+list2])], key=lambda x: x['score'], reverse=True)
list_new = [i for i in list1 if i in list2]

在 @cxyfreedom 的答案上稍微修改了下,其实这么多转换,我也看不过去了
weyou
2016-12-16 12:47:04 +08:00
@xiaolajiao 这个方法好
rogwan
2016-12-16 12:47:13 +08:00
@xiaolajiao 谢谢,我开始是用循环迭代去搞的

list_all = []
list1.extend(list2)
for temp in list1:
if temp not in list_all:
list_all.append(temp)
imn1
2016-12-16 12:51:04 +08:00
list_new = [i for i in list1 if i in list2]
l1 = [i for i in list1 if i not in list2]
l2 = [i for i in list2 if i not in list1]
list_all = list_new + l1 + l2
print(list_all)
imn1
2016-12-16 12:52:16 +08:00
@imn1
呃,要排序啊……忘了这个
cxyfreedom
2016-12-16 12:55:58 +08:00
@rogwan 第一个 all 的忘记去重了,下面那个人方法不错
leeyiw
2016-12-16 12:58:40 +08:00
s1 = set(list1)
s2 = set(list2)
list_all = list(s1.intersection(s2))
imn1
2016-12-16 13:02:14 +08:00
@leeyiw
这个 set 不报错么?
Yinz
2016-12-16 13:03:35 +08:00
@leeyiw unhashable type: 'dict'
Hstar
2016-12-16 13:30:08 +08:00
遇到过差不多的问题, 我是把 list 里面每一项转成 json 然后用 set 去重再转回来
rogwan
2016-12-16 14:03:44 +08:00
上面 @cxyfreedom @xiaolajiao @weyou 的方法推荐学习,感谢!
fatebe
2016-12-16 18:16:47 +08:00
for ..if .. in..
102400
2016-12-16 20:02:02 +08:00
ruby 可以直接 list1 | list2
zhx1991
2016-12-17 00:13:33 +08:00
如果要保存顺序的话好像只能循环的一个一个去看

如果不要顺序的话 linux 下 sort + comm 可以轻松做到各种集合结果
glogo
2016-12-17 03:07:05 +08:00
```
temp = []

def foo(x):
if x not in temp:
temp.append(x)
return x

print filter(foo, list1 + list2)
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/328043

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX