2011-07-06 31 views
18

給出一個列表如何在python中通過相似的索引/屬性對元組/對象列表進行分組?

old_list = [obj_1, obj_2, obj_3, ...] 

我想創建一個列表:

new_list = [[obj_1, obj_2], [obj_3], ...] 

其中obj_1.some_attr == obj_2.some_attr

我可以扔一些for循環和if檢查在一起,但這是醜陋的。有沒有pythonic的方式呢?順便說一下,對象的屬性都是字符串。

此外,還可以爲包含元組(長度相同)而不是對象的列表提供解決方案。

+0

_「包含元組(長度相同)而不是對象的列表」_這是否意味着**包含所有長度相同的元組的列表**?如果是,元組被分組的「屬性」是什麼? - 順便說一句,元組是對象,不是嗎? – eyquem

+0

@eyquem:1.是的; 2.元組按一定的索引分組。索引中的項目是一個字符串。我相信,但是我不確定。:-) – Aufwind

回答

31

defaultdict是這樣做的。

雖然for循環很重要,if語句不是。

from collections import defaultdict 


groups = defaultdict(list) 

for obj in old_list: 
    groups[obj.some_attr].append(obj) 

new_list = groups.values() 
+3

這當然不會保留(或以任何方式尊重)組的原始順序。所以它可能是也可能不是@Druss想要的。 – tjollans

+1

@ jollybox.de:「不保留(或以任何方式尊重)組的原始順序」正確。這是什麼時候成爲一項要求? –

+0

我不知道這是否是一項要求,原來的問題不明確。我原來是這樣讀的。仍然,很好的答案。 – tjollans

11

認爲你也可以嘗試使用itertools.groupby。請注意,下面的代碼只是一個示例,應根據您的需求進行修改:

data = [[1,2,3],[3,2,3],[1,1,1],[7,8,9],[7,7,9]] 

from itertools import groupby 

# for example if you need to get data grouped by each third element you can use the following code 
res = [list(v) for l,v in groupby(sorted(data, key=lambda x:x[2]), lambda x: x[2])]# use third element for grouping 
+1

基本上我的回答,但你忘了一個重要的方面:在使用'groupby'之前排序。 – JAB

+1

@JAB - 你的真相。謝謝你注意到我。 –

18

這裏有兩種情況。這都需要以下進口:

import itertools 
import operator 

您將使用itertools.groupby,要麼operator.attrgetteroperator.itemgetter

對於那些你被obj_1.some_attr == obj_2.some_attr分組的情況:

get_attr = operator.attrgetter('some_attr') 
new_list = [list(g) for k, g in itertools.groupby(sorted(old_list, key=get_attr), get_attr)] 

對於a[some_index] == b[some_index]:您所需要的排序,因爲itertools.groupby,使新組

get_item = operator.itemgetter(some_index) 
new_list = [list(g) for k, g in itertools.groupby(sorted(old_list, key=get_item), get_item)] 

注意當鍵的值變化。


注意,你可以用它來創建一個dict像美國洛特的回答,但沒有使用collections.defaultdict

使用字典解析(只對Python 3+,以及可能的Python 2.7,但我不知道):

groupdict = {k: g for k, g in itertools.groupby(sorted_list, keyfunction)} 

對於Python的早期版本,或作爲一種更簡潔的選擇:

groupdict = dict(itertools.groupby(sorted_list, keyfunction)) 
相關問題