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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.