views:

1778

answers:

5

Part of a programme builds this list,

[u'1 x Affinity for war', u'1 x Intellect', u'2 x Charisma', u'2 x Perception', u'3 x Population growth', u'4 x Affinity for the land', u'5 x Morale']

I'm currently trying to sort it alphabetically by the name of the evolution rather than by the number. Is there any way I can do this without just changing the order the two things appear in the list (as in 'intellect x 1)?

A: 

As you are trying to sort what is essentially custom data, I'd go with a custom sort.

Merge sort
Bubble sort
Quicksort

Teifion
No, you want to use the built-in sorting method with a custom comparator.
Adam Rosenfield
Is that what S.Lott has done? If not, would you be able to share a code example?
Teifion
It is what S. Lott has done.
recursive
This a terrible suggestion. He's trying to get something to sort, not to implement a sort. There is a big difference. One is useful and one is a waste of time.
ironfroggy
Yes, absolutely do not reinvent the wheel by writing a custom sort. Huge waste of time.
Kiv
+14  A: 

You have to get the "key" from the string.

def myKeyFunc( aString ):
    stuff, x, label = aString.partition(' x ')
    return label

aList.sort( key= myKeyFunc )
S.Lott
what do you mean by stuff?
Precisely and exactly what is says. That is just "stuff". "miscellaneous unspecified objects" according to a Thesaurus. The partition method of a string returns three results. One of those is just "stuff" that's never used again.
S.Lott
In this context, the stuff in front of the " x " might be meaningful, but we can't tell from the question what it is or what it means. Since the question is vague, we can only call it "stuff".
S.Lott
fair enough, thanks
Did you know that you can use underscores for parts of the tuple that you won't use: `_,_,label = aString.partition(' x ')`
Amoss
@Amoss: Some folks don't like it and prefer "real" variable names. Some folks prefer the `_`.
S.Lott
+1  A: 

Not knowing if your items are standardized at 1 digit, 1 space, 1 'x', 1 space, multiple words I wrote this up:

mylist = [u'1 x Affinity for war', u'1 x Intellect', u'2 x Charisma', u'2 x Perception', u'3 x Population growth', u'4 x Affinity for the land', u'5 x Morale']
def sort(a, b):
  return cmp(" ".join(a.split()[2:]), " ".join(b.split()[2:]))

mylist.sort(sort)

You can edit the parsing inside the sort method but you probably get the idea.

Cheers, Patrick

pboucher
Better to use key= than a custom comparator when you can because a custom comparator must be called n*log n times, but the key function only needs n calls.
recursive
Did not know that. Thanks recursive!
pboucher
+3  A: 

How about:

lst.sort(key=lamdba s: s.split(' x ')[1])
dF
A: 

To do so, you need to implement a custom compare:

def myCompare(x, y):
   x_name = " ".join(x.split()[2:])
   y_name = " ".join(y.split()[2:])
   return cmp(x_name, y_name)

Then you use that compare definition as the input to your sort function:

myList.sort(myCompare)
Justin Standard