2013-07-22 53 views
2

我有一個列表列表,基於每個列表的第一個元素,我想對列表進行排序。這些指數的樣本:使用數字後綴對不同長度的字符串進行排序

vlan1      
    usb0     
    eth1      
    vlan4     
    vlan20 

如果他們每個人都一樣長vlanX我會做這樣的事情:

table_data = sorted(table_data, key = lambda x: int(x[0][4:])) 

我想他們的方式,其中的VLAN來先排序,那麼其餘的都不重要。偉大的,如果他們排序,但不是必不可少的(我不認爲會有超過一個usb或eth)。

vlan1 
    vlan4 
    vlan20      
    usb0      
    eth1         

這是簡單的調整我的lambda做或我應該試試做一個函數來做到這一點?

我試過這個,但很明顯,它將usb和eth留在他們錯誤的地方,而排序vlans。

table_data = sorted(table_data, key = lambda x: x = True if "vlan" not in x[0] else int(x[0][4:])) 

編輯:該線程不回答我想要的?這將排列vlan元素之間的usb和eth元素,這不是我想要的。

+0

@Martijn彼得斯我認爲示例答案會以人類可讀的方式排序所有元素,這不是我想要的。這仍然使它足夠類似於關閉。我更喜歡分組相似的元素,然後對其相關的數字進行排序。 – Paul

+0

'table_data.sort(key = lambda x:(x [:4]!='vlan',int(x [4:] or 0)))' –

+0

@gnibbler我試過了,但沒有排序所有vlans正確。當我嘗試這些數字時,它給了我1,15,20,3。 – Paul

回答

1

您可以編寫一個函數來分割(前綴,索引)中的名稱,並將其傳遞給key參數。

import re 
table_data = ["vlan1", "usb0", "eth1", "vlan4", "vlan20"] 

def get_key(v): 
    prefix, index = re.match(r'([a-z]+)(\d+)', v).groups() 
    return prefix, -int(index) 

>>> sorted(table_data, key=get_key, reverse=True) 
['vlan1', 'vlan4', 'vlan20', 'usb0', 'eth1'] 

你想要的順序由前綴和升序降序按索引,函數索引轉換爲負,所以當列表被顛倒的順序是正確的。

[更新]

沒有,OP不希望爲了通過前綴下降。無論如何,OP都希望首先對「vlan」進行排序。這恰好符合降序字母排序,但如果將「wlan」鍵添加到數據中則不會。 - Martijn Pieters

不夠公平。

def get_key(v): 
    prefix, index = re.match(r'([a-z]+)(\d+)', v).groups() 
    if prefix == 'vlan': 
     prefix = '~' 
    return prefix, -int(index) 

>>> table_data = ["vlan1", "usb0", "eth1", "vlan4", "vlan20", "wlan0"] 
>>> sorted(table_data, key=get_key, reverse=True) 
['vlan1', 'vlan4', 'vlan20', 'wlan0', 'usb0', 'eth1'] 

如何組裝的字典?

interfaces = {} 
for iface in table_data: 
    prefix, index = re.match(r'([a-z]+)(\d+)', iface).groups() 
    interfaces.setdefault(prefix, []).append(iface) 
for v in interfaces.values(): 
    v.sort(key=lambda x: int(re.search(r'\d+', x).group(0))) 

>>> interfaces 
{'eth': ['eth1'], 
'usb': ['usb0'], 
'vlan': ['vlan1', 'vlan4', 'vlan20'], 
'wlan': ['wlan0']} 

>>> interface_types = interfaces.keys() 
>>> interface_types 
['eth', 'vlan', 'wlan', 'usb'] 

>>> interfaces['vlan'] 
['vlan1', 'vlan4', 'vlan20'] 
+0

不,OP不希望訂單按前綴降序。無論如何,OP都希望首先對「vlan」進行排序。這恰好符合降序字母排序,但如果將「wlan」鍵添加到數據中則不會。 –

+0

作爲@MartijnPieters說wlan在這裏是一個問題,當然可以在那裏。但很好的答案,我喜歡這個元組排序。 – Paul

+0

@Paul:已更新。 –

相關問題