在Python中用theirs属性分隔列表元素

时间:2018-03-07 09:07:01

标签: python

我有列表p1

p1 = [
    {'id': 1, 'area': 5},
    {'id': 2, 'area': 6},
    {'id': 3, 'area': 10},
    {'id': 4, 'area': 6},
    {'id': 5, 'area': 6},
    {'id': 6, 'area': 6},
    {'id': 7, 'area': 4},
    {'id': 8, 'area': 4}
]

我需要将此列表与area值分开,如下所示(p2):

p2 = {
    4: [
        {'id': 7, 'area': 4},
        {'id': 8, 'area': 4}
    ],
    5: [
        {'id': 1, 'area': 5}
    ],
    6: [
        {'id': 2, 'area': 6},
        {'id': 4, 'area': 6},
        {'id': 5, 'area': 6},
        {'id': 6, 'area': 6}
    ],
    10: [
        {'id': 3, 'area': 10}
    ]
}

我的解决方案是:

areas = {x['area'] for x in p1}
p2 = {}
for area in areas:
    p2[area] = [x for x in p1 if x['area'] == area]

它似乎有效,但有没有更好的,更“pythonic”的解决方案?

3 个答案:

答案 0 :(得分:3)

您只需使用defaultdict

即可
from collections import defaultdict

result = defaultdict(list)

for i in p1:
    result[i['area']].append(i)

答案 1 :(得分:3)

使用groupby即可获得

>>> import itertools
>>> f = lambda t: t['area']
>>> {i: list(b) for i, b in itertools.groupby(sorted(p1, key=f), key=f)}

给出

{4: [{'area': 4, 'id': 7}, 
     {'area': 4, 'id': 8}],
 5: [{'area': 5, 'id': 1}],
 6: [{'area': 6, 'id': 2},
     {'area': 6, 'id': 4},
     {'area': 6, 'id': 5},
     {'area': 6, 'id': 6}],
 10: [{'area': 10, 'id': 3}]}

编辑:如果您不喜欢使用lambdas,您也可以按照兄弟语言的建议进行操作

>>> import operator
>>> f = operator.itemgetter('area')

答案 2 :(得分:2)

是的,使用其中一个分组习语。使用香草dict

In [15]: p1 = [
    ...:     {'id': 1, 'area': 5},
    ...:     {'id': 2, 'area': 6},
    ...:     {'id': 3, 'area': 10},
    ...:     {'id': 4, 'area': 6},
    ...:     {'id': 5, 'area': 6},
    ...:     {'id': 6, 'area': 6},
    ...:     {'id': 7, 'area': 4},
    ...:     {'id': 8, 'area': 4}
    ...: ]

In [16]: p2 = {}

In [17]: for d in p1:
    ...:     p2.setdefault(d['area'], []).append(d)
    ...:

In [18]: p2
Out[18]:
{4: [{'area': 4, 'id': 7}, {'area': 4, 'id': 8}],
 5: [{'area': 5, 'id': 1}],
 6: [{'area': 6, 'id': 2},
  {'area': 6, 'id': 4},
  {'area': 6, 'id': 5},
  {'area': 6, 'id': 6}],
 10: [{'area': 10, 'id': 3}]}

或者更整洁地使用defaultdict

In [23]: from collections import defaultdict

In [24]: p2 = defaultdict(list)

In [25]: for d in p1:
    ...:     p2[d['area']].append(d)
    ...:

In [26]: p2
Out[26]:
defaultdict(list,
            {4: [{'area': 4, 'id': 7}, {'area': 4, 'id': 8}],
             5: [{'area': 5, 'id': 1}],
             6: [{'area': 6, 'id': 2},
              {'area': 6, 'id': 4},
              {'area': 6, 'id': 5},
              {'area': 6, 'id': 6}],
             10: [{'area': 10, 'id': 3}]})