1

I have a list of pitch and octave pairs that i would like to sort ascending or descending:

[['G', 2], ['D', 3], ['B', 3], ['A', 3], ['B', 3], ['D', 3], ['B', 3]]

First sorting should be done on the octave values. Thats easy as the octaves are integer values. My problem is that i don't know how to sort by pitch after sorting by octave. The order is (lowest to highest pitch):

C, D, E, F, G, A, B 

I think it's possible to do that in one line in python, but i don't even know how to do it in 100 lines ;)

Any help would be appreciated, thanks

  • no. h is just the german notation, meaning that german speaking people will use H instad of B. I wanted to provide this information. maybe it makes things more complicated! i'll remove it – nodFlindors Feb 06 '16 at 13:33
  • 1
    Welcome to the site! What have you tried so far? Python 2 or Python 3? Check out the [tour](http://stackoverflow.com/tour) for more about writing questions that will attract quality answers. BACH! – cxw Feb 06 '16 at 13:34
  • Yes, J.S.B.!! :) i used python 3 to extract the values from an xml file and i got a list similar to the one above. it just has more values. i could post my code here, but i think that would not help much... i guess i'm just missing a basic point here when it comes to understanding how i could use my list of pitches as a sort order. – nodFlindors Feb 06 '16 at 13:39
  • @nodFlindors It's okay, you can keep the H. I'll just give it the same value as B. – timgeb Feb 06 '16 at 13:45
  • @msw I think this question is more specific than the dupe target. OP needs to somehow define a custom order for his letters as well, instead of using the lexicographical order. – timgeb Feb 06 '16 at 14:00
  • @msw i stumbled upon the dupe you linked, but it didn't help me at all. I didn't understand that it could have been the soultion to my problem... – nodFlindors Feb 07 '16 at 14:05

1 Answers1

1

I think the cleanest way is to define a custom keyfunction:

>>> lst = [['G', 2], ['D', 3], ['B', 3], ['A', 3], ['B', 3], ['D', 3], ['B', 3]]
>>> pitch_order = {'C': 0, 'D': 1, 'E': 2, 'F': 3, 'G': 4, 'A': 5, 'B': 6, 'H': 6}    
>>> keyfun = lambda pair: (pair[1], pitch_order[pair[0]])
>>> sorted(lst, key=keyfun)
[['G', 2], ['D', 3], ['D', 3], ['A', 3], ['B', 3], ['B', 3], ['B', 3]]

This will sort by integer-value first and then by pitch (the letter) second.

timgeb
  • 76,762
  • 20
  • 123
  • 145
  • Ok. That seems to be exactly what i'm looking for. I will dig into the documentation so i actually learn something here and try it out on my lists and report back! Thank you so much :) – nodFlindors Feb 06 '16 at 13:53
  • @nodFlindors no problem, report back when your tests are through. – timgeb Feb 06 '16 at 13:55
  • Please explain the downvote and show me the better way how to do it. Thanks. – timgeb Feb 06 '16 at 14:08
  • Thanks, thats exactly what i was looking for and it helped me understand python a bit more. I also think that this question clarifies how to use a custom sort order. – nodFlindors Feb 07 '16 at 14:01