3

I want to convert a tuples list into a nested list using Python. How do I do that?

I have a sorted list of tuples (sorted by the second value):

[(1, 5),  (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), (12, 1), 
 (10, 1), (9, 1), (8, 1),  (7, 1), (6, 1), (2, 1)]

Now I want it to have like this (second value ignored and nested in lists):

[ [1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2] ]

I've seen other threads in here with map used for such things, but I don't completely understand it. Can anyone provide insight as to the 'correct' python way of doing this?

4

5 回答 5

11
from operator import itemgetter
from itertools import groupby

lst = [(1, 5),  (5, 4), (13, 3), (4, 3), (3, 2), (14, 1),
       (12, 1), (10, 1), (9, 1), (8, 1),  (7, 1), (6, 1), (2, 1)]

result = [[x for x, y in group]
          for key, group in groupby(lst, key=itemgetter(1))]

groupby(lst, key=itemgetter(1))生成连续元素组,lst其中所有元素都具有相同的第一个(从零开始计数)项。[x for x, y in group]保留每个组中每个元素的第 0 项。

于 2009-12-06T14:16:01.320 回答
2

这有点复杂,但您可以使用 itertools.groupby 函数来完成:

>>> lst = [(1, 5),  (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), (12, 1), 
 (10, 1), (9, 1), (8, 1),  (7, 1), (6, 1), (2, 1)]
>>> from operator import itemgetter 
>>> import itertools
>>> [map(itemgetter(0), group) for (key,group) in itertools.groupby(lst, itemgetter(1))]
[[1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2]]
>>> 

说明: groupby 为每个组返回一个迭代器,其中组定义为具有由作为单独参数传递的函数返回的相同值的条目序列。itemgetter(1) 生成一个函数,该函数在使用参数 x 调用时返回 x[1]。由于 groupby 迭代器返回两个值 - 使用的键和作为元组的原始值的序列,然后我们需要去除每个元组中的第二个值,这就是 map(itemgetter(0), group) 所做的。

于 2009-12-06T14:16:16.807 回答
1

也许不是最pythonesque的答案,但这有效:

d = {}

a = [(1,5), (5,4), (13,3), (4,3), (3,2), (14,1), (12,1)]

for value in a:
     if value[0] not in d:
         d[ value[0] ] = []
     d[ value[0] ].append( a[1] )

print d.values()
于 2009-12-06T14:17:18.277 回答
1

简单的解决方案:

n_list = []
c_snd = None
for (fst, snd) in o_list:
  if snd == c_snd: n_list[-1].append(fst)
  else:
    c_snd = snd
    n_list.append([fst])

说明:用于c_snd存储元组的当前第二部分。如果发生变化,n_list则为这个新的第二个值开始一个新列表,从 开始fst,否则添加fst到 中的最后一个列表n_list

于 2009-12-06T14:22:00.777 回答
0

不知道这对于更大的集合有多快,但你可以这样做:

input = [
    (1,  5), (5,  4), (13, 3), (4, 3), (3, 2), (14, 1),
    (12, 1), (10, 1), (9,  1), (8, 1), (7, 1), (6,  1),
    (2,  1)
]

output = [[] for _ in xrange(input[0][1])]
for value, key in input:
    output[-key].append(value)

print output # => [[1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2]]
于 2009-12-06T14:13:44.987 回答