1

I am using Python 3.2 and would like to sort a list of tuples based on a configuration file:

formats=CCC;aaa;BBB
providers=yy;QQ;TT

Each tuple contains this information:

( title, size, format, provider )

I would like this group of tuples to first be sorted by the providers list. All yy's come before QQ's and TT's.

Then, keeping this result order, move onto formats. All CCC's before aaa's before BBB's.

Finally, the third criteria would be to sort by size (float), in decending order.

It is critical that each step uses a stable sort so that the secondary sort keeps the ordering of the first sort and so on.

How can I do this in a pythonic way? Thanks.

EDIT 1

This is what I tried, my it will obviously not work because of sorted(mydata). mydata can't be a list in this context.

providers="yy;QQ;TT"
formats="CCC;aaa;BBB"

p_dict = {}
f_dict = {}

for k,v in enumerate(providers.split(';')):
    p_dict[k] = v

for k,v in enumerate(formats.split(';')):
    f_dict[k] = v

mydata = (
                ('title1', 423.4, 'QQ', 'aaa'),
                ('title2', 523.2, 'TT', 'CCC'),
                ('title3', 389.0, 'yy', 'aaa'),
                ('title4', 503.2, 'QQ', 'BBB') )

sort1 = sorted( mydata, key=p_dict.__getitem__)
print(sort1)
1
  • 2
    If you ask about a pythonic way, what's the way you've come up with so far? What code do you use to split the input? What individual sort function have you tried? Commented Jul 10, 2012 at 13:54

4 Answers 4

3
def sort_key(data):
    title, size, format, provider = data
    return p_dict[provider], f_dict[format], -size 

print sorted( mydata, key = sort_key)

Basically, devise a key function that produces tuples that will sort in the desired order.

Sign up to request clarification or add additional context in comments.

2 Comments

I think this is very close to working. I changed my code to "p_dict[v] = k" and "f_dict[v] = k"
I was able to get this working within my program. Thanks again!
2

This is basically @Winston Ewert's answer, but it's complete working code. Note that you can create a dictionary by passing an iterable to dict(); here we make a generator expression to swap around the result we get from enumerate().

providers="yy;QQ;TT"
formats="CCC;aaa;BBB"

d_providers = dict((k, v) for v, k in enumerate(providers.split(';')))
d_formats = dict((k, v) for v, k in enumerate(formats.split(';')))

def key_mydata(m):
    return (d_providers[m[2]], d_formats[m[3]], -m[1], m[0])

mydata = (
                ('title1', 423.4, 'QQ', 'aaa'),
                ('title2', 523.2, 'TT', 'CCC'),
                ('title3', 389.0, 'yy', 'aaa'),
                ('title4', 503.2, 'QQ', 'BBB') )

sort1 = sorted(mydata, key=key_mydata)
print(sort1)

2 Comments

Thanks, this is a great answer, but feel compelled to give Winston the check mark. Great idea about the dict.
No worries; he did answer it first, and besides I have plenty of points.
1

Create sequences of the formats and providers, then use a compound key (read: tuple) that looks up the indexes of the values in the current element.

1 Comment

Can you please elaborate? I am just not following this. Thanks.
0

Use a key function that converts each part to an index:

providers = providers.split(';')
formats = formats.split(';')
def sort_key(item):
    title, size, format, provider = item
    return (providers.index(provider), formats.index(format), -size, title)
print(sorted(mydata, key=sort_key))

Note that Python sorting is stable, so you could also e.g. sort by size descending first, then by format, then by provider.

2 Comments

Doesn't sort_key has to take a single parameter, not four?
What I don't like about this: list.index() is O(N) where N is the length of the list. For short lists it would be okay, but for longer lists it would be better to build a dict() that maps each value onto its index value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.