按值分组

比方说,我有这样一个列表:

list = [["A",0], ["B",1], ["C",0], ["D",2], ["E",2]] 

我怎样才能最优雅的组合这个得到这个列表输出在Python中:

 list = [["A", "C"], ["B"], ["D", "E"]] 

所以这些值是按secound值分组的,但顺序是保留的。

 values = set(map(lambda x:x[1], list)) newlist = [[y[0] for y in list if y[1]==x] for x in values] 
 from operator import itemgetter from itertools import groupby lki = [["A",0], ["B",1], ["C",0], ["D",2], ["E",2]] lki.sort(key=itemgetter(1)) glo = [[x for x,y in g] for k,g in groupby(lki,key=itemgetter(1))] print glo 

编辑

另一种不需要导入的解决scheme更具有可读性,可以保持订单,比前一版本长22%

 oldlist = [["A",0], ["B",1], ["C",0], ["D",2], ["E",2]] newlist, dicpos = [],{} for val,k in oldlist: if k in dicpos: newlist[dicpos[k]].extend(val) else: newlist.append([val]) dicpos[k] = len(dicpos) print newlist 

霍华德的回答简洁而优雅,但在最坏的情况下也是O(n ^ 2)。 对于包含大量分组键值的大型列表,您需要先对列表进行sorting,然后使用itertools.groupby

 >>> from itertools import groupby >>> from operator import itemgetter >>> seq = [["A",0], ["B",1], ["C",0], ["D",2], ["E",2]] >>> seq.sort(key = itemgetter(1)) >>> groups = groupby(seq, itemgetter(1)) >>> [[item[0] for item in data] for (key, data) in groups] [['A', 'C'], ['B'], ['D', 'E']] 

编辑:

在看到eyequem的答案后,我改变了这个: itemgetter(1)lambda x: x[1]更好。

 >>> import collections >>> D1 = collections.defaultdict(list) >>> for element in L1: ... D1[element[1]].append(element[0]) ... >>> L2 = D1.values() >>> print L2 [['A', 'C'], ['B'], ['D', 'E']] >>> 

我不知道优雅,但肯定是可行的:

 oldlist = [["A",0], ["B",1], ["C",0], ["D",2], ["E",2]] # change into: list = [["A", "C"], ["B"], ["D", "E"]] order=[] dic=dict() for value,key in oldlist: try: dic[key].append(value) except KeyError: order.append(key) dic[key]=[value] newlist=map(dic.get, order) print newlist 

这保留了每个键的第一次出现的顺序,以及每个键的项目顺序。 它要求密钥是可哈希的,但是并不赋予其意义。

 len = max(key for (item, key) in list) newlist = [[] for i in range(len+1)] for item,key in list: newlist[key].append(item) 

你可以在一个单一的列表理解,也许更优雅,但O(n ** 2):

 [[item for (item,key) in list if key==i] for i in range(max(key for (item,key) in list)+1)]