我有一个列表列表,基于每个列表的第一个元素我想对列表进行排序。这些指数的样本:
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']
