4

I have strings that look like "co1/co2", "co3/co4" ... "co11/co12"

describing it as a regex:

^(?P<prefix>\w\w)(?P<month>\d+)/(?P<prefix2>\w\w)(?P<month2>\d+)$   

I want to sort a collection of these strings based on the equivalent of the "month" group of the regex. (the first number in the string (eg. the "1" in 'co1/co2' or the "12" in 'co12/co13')

I'm unable to figure out a lambda function I can use in sorted() that will do this for me, though.

wrong_order = [u'co1/co2', u'co10/co11', u'co11/co12', u'co12/co13', u'co2/co3',
       u'co3/co4', u'co4/co5', u'co5/co6', u'co6/co7', u'co7/co8', u'co8/co9',
       u'co9/co10']


correct_order = [u'co1/co2', u'co2/co3', u'co3/co4', u'co4/co5', u'co5/co6', \
u'co6/co7', u'co7/co8', u'co8/co9', u'co9/co10', u'co10/co11', u'co11/co12', u'co12/co13']


#this lambda function doesn't work
output = sorted(wrong_order, key=lambda x: (x[2:]))
2
  • your solution would work if the numbers always had the same number of digits. e.g. co02 instead of co2 Commented Oct 14, 2015 at 9:29
  • What you want is numeric sort, but x[2:] is a string. You need to convert that string to a number Commented Oct 14, 2015 at 9:31

2 Answers 2

5

Without a regex:

lambda x: int(x.partition('/')[0][2:])

This takes the part of the string before the /, then everything but the starting co, then converts that to an integer.

I used str.partition() as it is faster than str.split() for the split only once case.

Demo:

>>> wrong_order = [u'co1/co2', u'co10/co11', u'co11/co12', u'co12/co13', u'co2/co3',
...        u'co3/co4', u'co4/co5', u'co5/co6', u'co6/co7', u'co7/co8', u'co8/co9',
...        u'co9/co10']
>>> sorted(wrong_order, key=lambda x: int(x.partition('/')[0][2:]))
[u'co1/co2', u'co2/co3', u'co3/co4', u'co4/co5', u'co5/co6', u'co6/co7', u'co7/co8', u'co8/co9', u'co9/co10', u'co10/co11', u'co11/co12', u'co12/co13']
Sign up to request clarification or add additional context in comments.

Comments

3

try this:

>>> sorted(wrong_order, key = lambda x:int(x.split("/")[0][2:]))
[u'co1/co2', u'co2/co3', u'co3/co4', u'co4/co5', u'co5/co6', u'co6/co7', u'co7/co8', u'co8/co9', u'co9/co10', u'co10/co11', u'co11/co12', u'co12/co13']

Lambda whats it doing, first it split with "/" and select the 1st value and select the value after 1 index and convert to integer

Comments

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.