2013-07-22 47 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:已更新。 –

相关问题