让我说我有一个班级:
class Cat(object):
color = "White" # "Black", "Red" or whatever
name = "..."
....
如果我有一个猫的列表,我想用颜色将它们分开并放入列表字典中:
cats = [cat1, cat2, cat3, ...]
cats_by_color = {"White": [cat1, cat3, ...], "Black": [...], ...}
现在我这样做:
cats_by_color ={}
for cat in cats:
if cat.color not in cats_by_color.keys(): # add new key if needed
cats_by_color[cat.color] = []
cats_by_colors[cat.color].append(cat) # add cat to right list
我有一种强烈的感觉,就是有一种“更加诡异的方式”来做这些事情。怎么做一些单线程?
答案 0 :(得分:4)
from collections import defaultdict
cats_by_color = defaultdict(list)
for cat in cats:
cats_by_colors[cat.color].append(cat)
答案 1 :(得分:0)
要在单行中进行,您需要先对列表进行排序,然后使用itertools.groupby()
:
from operator import attrgetter
from itertools import groupby
color = attrgetter('color')
cats_by_color = {k: list(g) for k, g in groupby(sorted(cats, key=color), color)}
但是,排序比直接循环更昂贵;这不再是单行,但使用collections.defaultdict()
至少会使其变得紧凑:
from collections import defaultdict
cats_by_color = defaultdict(list)
for cat in cats:
cats_by_colors[cat.color].append(cat)
此处defaultdict
将为尚未出现在字典中的密钥创建新的list
对象,只需尝试访问密钥即可。
答案 2 :(得分:0)
如果你真的想要一行,没有任何进口:
cats_by_colors = {color: [cat for cat in cats if cat.color == color]
for color in set(cat.color for cat in cats)}
但是,因为这会为每个cats
迭代所有color
(并且一次获得颜色),效率不高!
请注意,您的Cat
属性目前是类,而非实例属性,应该是:
class Cat:
def __init__(self, color, name):
self.color = color
self.name = name