mix
mix

Reputation: 7151

best method and data structure for sorting a list of tuples into multiple lists?

Let's say I have a list of tuples like this:

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

and that I want to sort these tuples into multiple lists, each grouped by the first element in the tuples. Further, once grouped into those lists, I want the new lists reverse sorted by the second element (the int). So, the result would be:

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

Perhaps I could forego the multiple lists and make a list of lists of tuples? So, I would get:

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

But even in this case, how would I get the internal lists reverse sorted by the second element?

If I'm going about this the wrong way, please mention it. I'm still new at Python. Thx!

Upvotes: 1

Views: 2110

Answers (3)

mouad
mouad

Reputation: 70049

You can do something like this:

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))]

Output :

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

Upvotes: 2

Zach Kelling
Zach Kelling

Reputation: 53849

Well, you can get your lists easily with a list comprehension:

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']

You can even sort them in place

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

I'd just use a dict, personally. Simple data structures are best.

from collections import defaultdict

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

Which would give you something like:

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

But then that's my solution for everything so maybe I need to branch out a little.

Upvotes: 3

Mikko Ohtamaa
Mikko Ohtamaa

Reputation: 83556

What I would do in a case like this is a dictionary of lists.

things = {}

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

Then you can iterate through "things" using things.keys() or things.values()

E.g.

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

Upvotes: 0

Related Questions