2012-12-26 73 views
0

我有列表的字典和列表包含字典,像这样:删除常见的元素,从列表的字典在python

my_dict = { 
'list1': [{'catch': 100, 'id': '1'}, {'catch': 101, 'id': '2'}, 
      {'catch': 50, 'id': '1'}], 
'list2': [{'catch': 189, 'id': '1'}, {'catch': 120, 'id': '12'}], 
'list3': [{'catch': 140, 'id': '1'}, {'catch': 10, 'id': '100'}] 
} 

什么是commin删除列表项的最Python的方式“ ID'值并将它们存储在单独的列表中?所以输出会是这样的:

my_dict = { 
'list1': [{'catch': 101, 'id': '2'}], 
'list2': [{'catch': 120, 'id': '12'}], 
'list3': [ {'catch': 10, 'id': '100'}], 
'list4': [{'catch': 100, 'id': '1'}, , {'catch': 50, 'id': '1'}, 
      {'catch': 189, 'id': '1'}, {'catch': 140, 'id': '1'}] 
} 

在我的节目我也与此类似7名列表,如果“身份证”出现在两个或两个以上这些名单,我想存储的悉数亮相在第八届列表 'ID' 作进一步处理项目

与问候, finnurtorfa

+5

也许是时候重新考虑你的数据结构了吧? –

+0

@MartijnPieters而我完全同意 - 的时候会发生这种情况是从基于文档的数据库返回的对象列表... –

+0

什么是字典键点现实生活中的例子吗?我忽略了他们在我的答案,因为它似乎他们并不真正意味着什么,但也许他们这样做...... – katrielalex

回答

2
>>> get_id = operator.itemgetter("id") 
>>> flattened_dict = itertools.chain.from_iterable(my_dict.values()) 
>>> groups = itertools.groupby(sorted(flattened_dict, key=get_id), get_id) 
>>> {k: list(v) for k, v in groups} 
{'1': [{'catch': 100, 'id': '1'}, 
    {'catch': 50, 'id': '1'}, 
    {'catch': 140, 'id': '1'}, 
    {'catch': 189, 'id': '1'}], 
'100': [{'catch': 10, 'id': '100'}], 
'12': [{'catch': 120, 'id': '12'}], 
'2': [{'catch': 101, 'id': '2'}]} 

说明:

  • get_id是取对象x并返回x["id"]的函数。
  • flattened_dict仅仅是一个迭代在所有的列表(即连接所有.values()my_dict
  • 现在,我们的排序与键功能get_idflattened_dict的 - 那就是,排序ID - 和组结果由ID

这基本上可行的,因为itertools.groupby是真棒

+0

问题要问你:你如何保持代码的高尔夫这个问题的答案,如果你努力去兑现OP的需要移除的共同要素现有的名单,并把它们放入其他的?在你的解决方案中,list1 2 3被重新编号。 – Boud

+0

我不会把这个代码打高尔夫球。我想“使用强大的工具,Python的为您提供免费的”调用它。 – katrielalex

+0

为了回答你的问题,这会有点痛苦,但是完全可行 - 但由于我不清楚OP究竟需要什么,所以我不愿意编写需求来编写令人讨厌的代码。 – katrielalex

0

沿着以下行的东西:

my_dict = { 
'list1': [{'catch': 100, 'id': '1'}, {'catch': 101, 'id': '2'}, 
     {'catch': 50, 'id': '1'}], 
'list2': [{'catch': 189, 'id': '1'}, {'catch': 120, 'id': '12'}], 
'list3': [{'catch': 140, 'id': '1'}, {'catch': 10, 'id': '100'}] 
} 

from itertools import groupby 

sub = {} 
for k in my_dict: 
for kk, g in groupby(my_dict[k], lambda v: v["id"]): 
    if not kk in sub: 
    sub[kk] = [] 
    sub[kk] = sub[kk] + list(g) 

print sub 

{'1': [{'catch': 100, 'id': '1'}, {'catch': 50, 'id': '1'}, {'catch': 140, 'id': '1'}, {'catch': 189, 'id': '1'}], '12': [{'catch': 120, 'id': '12'}], '100': [{'catch': 10, 'id': '100'}], '2': [{'catch': 101, 'id': '2'}]} 
3

考虑转型您的数据弄成这个样子:

>>> import itertools 
>>> { k: [d['catch'] for d in v] for k, v in itertools.groupby(sorted(itertools.chain(*my_dict.itervalues()), key=lambda d: d['id']), lambda d: d['id']) } 
{'1': [100, 50, 140, 189], '2': [101], '100': [10], '12': [120]} 

您还没有描述数据代表什么,所以这可能并不适合你。但使用的工具(chaingroupbyitertools)应该至少给你一些想法。

编辑:我在测试中偶然使用了问题中的示例答案。通过向输入groupby添加排序来修复。

+0

同意。所有数据实际上都是('id,catch')对的集合,您可以将它们存储为'id:[catch]'的字典。 – katrielalex

+0

你可能想使用'chain.from_iterable',这样你就可以迭代这些值了。 – katrielalex

相关问题