3

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

  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 元素进行排序,这不是我想要的。

4

1 回答 1

2

您可以编写一个函数来拆分(前缀,索引)中的名称,并将其传递给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”键添加到数据中,则不适合。——马丁·彼得斯

很公平。

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']
于 2013-07-22T11:50:08.750 回答