2016-12-30 120 views
0

我有不同的分类与我一个详尽的清单:拆分Python列表并将其存储在单独的列表

myList = [ 
    {'name': 'Sasha', 'category': 'Dog'}, 
    {'name': 'Meow', 'category': 'Cat'}, 
    {'name': 'Bark', 'category': 'Dog'} 
] 

我希望他们能够打破这bigList内创建更小的列表。这将是与此类似:

bigList = [ 
    [ 
    {'category': 'Dog', 'name': 'Sasha'}, 
    {'category': 'Dog', 'name': 'Bark'} 
    ], 
    [ 
    {'category': 'Cat', 'name': 'Meow'} 
    ] 
] 

这里是迭代循环蟒蛇逻辑:

bigList = [] 
prev = '' 

for s in myList: 
     newList = [] 
     if s['category'] != prev: 
      for m in myList: 
       if m['category'] == s['category']: 
        newList.append(m) 
      bigList.append(newList) 
     prev = s['category'] 

这样做的伎俩对我,但我想知道我怎么能优化上述for循环中的更多更短和更高效的代码。

+1

可能会更好地适应[代码审查网站(http://codereview.stackexchange.com/)。 – alecxe

+0

这样做会很快。 – xxCodexx

+0

查看'itertools',特别是['groupby'](https://docs.python.org/2/library/itertools.html#itertools.groupby) – roganjosh

回答

2

您可以用groupby两个步骤@roganjosh作为评论做到这一点:

from itertools import groupby 

# step 1: sort the list by category, we need this step because groupby only groups same 
# adjacent values so we need to sort the list so that same category are close to each other 
sort_list = sorted(myList, key = lambda x: x["category"]) 

# step 2: group by the category and create a new sub list for each group 
[list(g) for _, g in groupby(sort_list, key = lambda x: x['category'])] 


#[[{'category': 'Cat', 'name': 'Meow'}], 
# [{'category': 'Dog', 'name': 'Sasha'}, {'category': 'Dog', 'name': 'Bark'}]] 
1

排序可以为大型列表昂贵。

与您的数据开始:

my_list = [ 
    {'name': 'Sasha', 'category': 'Dog'}, 
    {'name': 'Meow', 'category': 'Cat'}, 
    {'name': 'Bark', 'category': 'Dog'} 
] 

这遍历一旦你的列表中的所有元素,并rembers什么它已经在字典中见过:

res = [] 
seen = {} 
for entry in my_list: 
    val = seen.setdefault(entry['category'], []) 
    if not val: 
     res.append(val) 
    val.append(entry) 

它附加一个新的列表只对于还没有看到的条目为res,但是它从seen字典获得的对应嵌套列表val的所有条目。所以,同样valresseen。因此,追加到val将放大val,无论您访问valres和或seen,都可以看到效果。行val = seen.setdefault(entry['category'], [])为您提供一个现有列表,如果该类别在之前出现过,或者如果该类别第一次遇到,则为一个新的空列表。同时,如果该类别尚未在seen中,它将添加一个带有空列表的新密钥作为seen的值。

这是结果:

import pprint 

pprint.pprint(res) 

[[{'category': 'Dog', 'name': 'Sasha'}, {'category': 'Dog', 'name': 'Bark'}], 
[{'category': 'Cat', 'name': 'Meow'}]] 
+0

这是否适合您? –