【问题标题】:Split python list in filtered list of multiple list and store them in single list在多个列表的过滤列表中拆分python列表并将它们存储在单个列表中
【发布时间】:2016-12-30 15:36:16
【问题描述】:

我有一份详尽的不同类别清单:

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'}
   ]
]

这是迭代循环的python逻辑:

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 循环中的上述逻辑以获得更短和更高效的代码。

【问题讨论】:

标签: python django list for-loop


【解决方案1】:

您可以使用@roganjosh 评论的groupby 分两步完成此操作:

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'}]]

【讨论】:

    【解决方案2】:

    对于大型列表,排序可能会很昂贵。

    从您的数据开始:

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

    这将遍历列表中的所有元素一次,并记住它之前在字典中已经看到的内容:

    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 将放大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'}]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-30
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多