对元组列表进行排序并分成多个列表的最佳方法和数据结构?

1 投票
3 回答
2098 浏览
提问于 2025-04-16 19:14

假设我有一个这样的元组列表:

l = [('music','300','url'),('movie','400','url'),
('clothing','250','url'),('music','350','url'),
('music','400','url'),('movie','1000','url')]

我想把这些元组按照第一个元素分成多个列表。然后,在分组后,我还想根据第二个元素(一个整数)对这些新列表进行倒序排序。最终的结果应该是:

music = [('music','400','url'),('music','350','url'),('music','300','url')]
movie = [('movie','1000','url'),('movie','400','url')]
clothing = [('clothing','250','url')]

也许我可以不使用多个列表,而是创建一个包含元组的列表的列表?这样我会得到:

sortedlist = [[('music','400','url'),('music','350','url'),('music','300','url')],
[('movie','1000','url'),('movie','400','url')],
[('clothing','250','url')]]

但即使这样,我该如何让内部列表根据第二个元素进行倒序排序呢?

如果我这样做不对,请告诉我。我对Python还很陌生。谢谢!

3 个回答

0

在这种情况下,我会使用一个字典,里面放的是列表。

things = {}

for tuple in all_tuples:
    key = tuple[0]
    if not key in things:
        things[key] = [] # Initialize empty list
    things[key].append(tuple)

然后你可以通过使用 things.keys() 或 things.values() 来遍历“东西”。

比如说:

things["music"] = [('music','400','url'),('music','350','url'),('music','300','url')]
2

你可以这样做:

import itertools
import operator

sorted_l = sorted(l, key=lambda x: (x[0], int(x[1])), reverse=True)

print [list(g[1]) for g in itertools.groupby(sorted_l, key=operator.itemgetter(0))]

输出结果:

[[('music', '400', 'url'), ('music', '350', 'url'), ('music', '300', 'url')],
 [('movie', '1000', 'url'), ('movie', '400', 'url')],
 [('clothing', '250', 'url')]]
3

好吧,你可以通过列表推导式轻松获取你的列表:

music = [x for x in l if x[0] == 'music']
movie = [x for x in l if x[0] == 'movie']
clothing = [x for x in l if x[0] == 'clothing']

你甚至可以直接对它们进行排序

>>> music.sort(key=lambda x: x[1], reverse=True)
<<< [('music', '400', 'url'), ('music', '350', 'url'), ('music', '300', 'url')]

我个人会选择使用字典。简单的数据结构是最好的。

from collections import defaultdict

d = defaultdict(list)
for x in l:
    d[x[0]].append(x[1:])

这样你就能得到类似这样的东西:

>>> for k,v in d.iteritems():
...:     print k, v
...:
...:
movie [('400', 'url'), ('1000', 'url')]
clothing [('250', 'url')]
music [('300', 'url'), ('350', 'url'), ('400', 'url')]

不过这可能是我对所有问题的解决方案,所以也许我需要尝试一些不同的东西。

撰写回答