假设我有一个这样的列表:
list = [["A",0], ["B",1], ["C",0], ["D",2], ["E",2]]
我怎样才能最优雅地将其分组以在Python中获取此列表输出:
list = [["A", "C"], ["B"], ["D", "E"]]
因此值按secound值分组,但订单仍然保留......
答案 0 :(得分:77)
values = set(map(lambda x:x[1], list))
newlist = [[y[0] for y in list if y[1]==x] for x in values]
答案 1 :(得分:27)
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
修改
另一个不需要导入的解决方案,更具可读性,保留订单,比前一个解决方案长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
答案 2 :(得分:20)
霍华德的答案简洁而优雅,但在最坏的情况下也是O(n ^ 2)。对于包含大量分组键值的大型列表,您需要先对列表进行排序,然后使用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]
更好。
答案 3 :(得分:7)
>>> 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']]
>>>
答案 4 :(得分:2)
我不知道优雅,但它确实可行:
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
这保留了每个键的第一次出现的顺序,以及每个键的项目顺序。它要求密钥可以清除,但不能为其赋予意义。
答案 5 :(得分:1)
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)]
答案 6 :(得分:0)
>>> xs = [["A",0], ["B",1], ["C",0], ["D",2], ["E",2]]
>>> xs.sort(key=lambda x: x[1])
>>> reduce(lambda l, x: (l.append([x]) if l[-1][0][1] != x[1] else l[-1].append(x)) or l, xs[1:], [[xs[0]]]) if xs else []
[[['A', 0], ['C', 0]], [['B', 1]], [['D', 2], ['E', 2]]]
基本上,如果列表已排序,则可以通过查看由先前步骤构建的最后一个组来reduce
-您可以判断是否需要启动新组或修改现有组。 ... or l
位是使我们能够在Python中使用lambda
的技巧。 ({append
返回None
。返回比None
更有用的东西总是更好,但是,Python,例如Python。)