我有一个列表列表,基于我想要对列表进行排序的每个列表的第一个元素。这些指数的样本:
vlan1
usb0
eth1
vlan4
vlan20
如果它们的长度与vlanX相同,我会做类似的事情:
table_data = sorted(table_data, key = lambda x: int(x[0][4:]))
我想以一种先出现的方式对它们进行排序,然后其余的并不重要。好的,如果它们已经分类但不是必需的(我认为不会有超过一个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 :(得分: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']