2013-11-28 4 views
0

Я в настоящее время пытается упорядочить список вида:Python буквенно-цифровой сортировки для списка списков

[["Chr1", "949699", "949700"],["Chr11", "3219", "444949"], 
["Chr10", "699", "800"],["Chr2", "232342", "235345234"], 
["ChrX", "4567", "45634"],["Chr1", "950000", "960000"]] 

Использование встроенного sorted(), я получаю:

[[ «Chr1», '949699', '949700'], ['Chr1', '950000', '960000'], ['Chr10', '699', '800'], ['Chr11', '3219', '444949'] , ['Chr2', '232342', '235345234'], ['ChrX', '4567', '45634']]

, но я хочу, чтобы «Chr2» появился перед «Chr10». Мое текущее решение включает в себя код, адаптированные страницах: Does Python have a built in function for string natural sort?

Моего текущим решение выглядит следующим образом:

import re 

def naturalSort(l): 
    convert= lambda text: int(text) if text.isdigit() else text.lower() 
    alphanum_key= lambda key: [convert(c) for c in re.split('([0-9]+)', key)] 
    if isinstance(l[0], list): 
     return sorted(l, key= lambda k: [alphanum_key(x) for x in k]) 
    else: 
     return sorted(l, key= alphanum_key) 

Уступая правильный порядок:

[['Chr1', '949699', '949700'], ['Chr1', '950000', '960000'], ['Chr2', '232342', '235345234'], ['Chr10', '699', '800'], ['Chr11', '3219', '444949'], ['ChrX', '4567', '45634']] 

Есть ли лучший способ сделать это ?

+0

Это называется 'естественной сортировки'. –

+0

А .. но я думаю, что это может быть не обман, так как он пытается создать его сам. Но этот вопрос может быть лучше подходит для http://codereview.stackexchange.com – aIKid

+0

Я привел страницу естественной сортировки. Я специально задаю вопрос о сортировке списка списков. – Megatron

ответ

0

ли это нравится:

In [1]: l = [["Chr1", "949699", "949700"],["Chr11", "3219", "444949"],["Chr10", "699", "800"],["Chr2", "232342", "235345234"],["ChrX", "4567", "45634"],["Chr1", "950000", "960000"]] 

In [2]: sorted(l, key=lambda x: int(x[0].replace('Chr', '')) if x[0].replace('Chr', '').isdigit() else x[0]) 
Out[2]: 
[['Chr1', '949699', '949700'], 
['Chr1', '950000', '960000'], 
['Chr2', '232342', '235345234'], 
['Chr10', '699', '800'], 
['Chr11', '3219', '444949'], 
['ChrX', '4567', '45634']] 

Или более элегантный вариант:

sorted(l, key=lambda x: int(''.join([i for i in x[0] if i.isdigit()])) if re.findall(r'\d+$', x[0]) else x[0]) 
+0

Вход не всегда имеет форму. Иногда это может быть просто «1», «2», «11», «X» без префикса «Chr». – Megatron

+0

Изменен сортировщик как 'sorted (l, key = lambda x: int (''. Join ([i для i в x [0], если i.isdigit()])), если [i для i в x [0] if i.isdigit()] else x [0]) ' – greg

+0

Более интересный вариант:' import re; sorted (l, key = lambda x: int (''. join ([i для i в x [0], если i.isdigit()])), если re.findall (r '\ d + $', x [0]) else x [0]) ' – greg

0

Вот более компактное решение:

natkey = lambda e: [x or int(y) for x, y in re.findall(r'(\D+)|(\d+)', e)] 
print sorted(data, key=lambda item: map(natkey, item)) 

 Смежные вопросы

  • Нет связанных вопросов^_^