2016-08-24 41 views
6

如何通過數字值對此列表進行排序?是否需要使用正則表達式來刪除數字或者是否有更多的Pythonic方法來執行此操作?基於數字的混合字符串排序列表

to_sort 

['12-foo', 
'1-bar', 
'2-bar', 
'foo-11', 
'bar-3', 
'foo-4', 
'foobar-5', 
'6-foo', 
'7-bar'] 

希望的輸出如下所示:

1-bar 
2-bar 
bar-3 
foo-4 
foobar-5 
6-foo 
7-bar 
foo-11 
12-foo 
+1

對於我來說,最「Python化」的方式是最明顯的一個。不要總是嘗試Python方式的一切,但更多關注可讀性和良好實踐。 – Maroun

+0

@idjaw我曾嘗試用'鍵'排序',但下面的答案幫助我更好地理解這一點。 – ade1e

+0

@adele總是張貼你的嘗試,我們總是從對方的錯誤中學習。錯誤的嘗試是非常有幫助的。 – Maroun

回答

10

一種解決方案是以下的正則表達式提取:

sorted(l, key=lambda x: int(re.search('\d+', x).group(0))) 

>>> l 
['12-foo', '1-bar', '2-bar', 'foo-11', 'bar-3', 'foo-4', 'foobar-5', '6-foo', '7-bar'] 
>>> sorted(l, key=lambda x: int(re.search('\d+', x).group(0))) 
['1-bar', '2-bar', 'bar-3', 'foo-4', 'foobar-5', '6-foo', '7-bar', 'foo-11', '12-foo'] 

key是提取的數位(換算成int以避免按照光學字詞排序)。

4

如果你不想使用正則表達式

>>> l = ['12-foo', '1-bar', '2-bar', 'foo-11', 'bar-3', 'foo-4', 'foobar-5', '6-foo', '7-bar'] 

>>> sorted(l, key = lambda x: int(''.join(filter(str.isdigit, x)))) 

['1-bar', '2-bar', 'bar-3', 'foo-4', 'foobar-5', '6-foo', '7-bar', 'foo-11', '12-foo'] 
+2

如果輸入很長,請運行這兩個實現並查看哪一個更快。 'filter(std.isdigit,x)'創建一個很長的(每個字符)臨時列表,這個列表可能很慢。 – pts

+0

沒錯,過濾器可能比基因xp更慢。 –

+0

我已經標記了答案,因爲這有助於我的理解,並且很有趣地看到你如何使用'isdigit'。謝謝 – ade1e