Skip to main content
 首页 » 编程设计

python之使用数字后缀对不同长度的字符串进行排序

2025年05月04日19leader

我有一个列表列表,基于每个列表的第一个元素我想对列表进行排序。这些指数的样本:

  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 是否很简单,还是我应该尝试创建一个函数来完成它?

我试过了,但很明显它在对 vlan 进行排序时将 usb 和 eth 留在了错误的位置。

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

编辑:那个线程没有回答我想要的?这会在 vlan 元素之间对 usb 和 eth 元素进行排序,这不是我想要的。

请您参考如下方法:

您可以编写一个函数将名称拆分为 (prefix, index),并将其传递给 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'] 

您希望顺序按前缀降序并按索引升序,该函数将索引转换为负数,以便在列表反转时顺序正确。

[更新]

No, the OP does not want the order to be descending by prefix. The OP wants 'vlan' to be sorted first, regardless. That happens to fit with descending alphabetic sorting, but not if a 'wlan' key was ever added to the data. – 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']