我有这个元组:
[('site-nfv01-swsto01',), ('site-nfv01-swsto01V',),('site-nfv01-swsto02',),('site-nfv02-swsto02',), ('site-nfv02-swsto01',) , ('site-nfv02-swsto01V',)]我想按以下顺序进行分类:
site-nfv01-swsto01V
site-nfv01-swsto01
site-nfv01-swsto02
site-nfv02-swsto01V
site-nfv02-swsto01
site-nfv02-swsto02拥有:[('site-nfv01-swsto01V',), ('site-nfv01-swsto01',),('site-nfv01-swsto02',),('site-nfv02-swsto01V',), ('site-nfv02-swsto01',) , ('site-nfv02-swsto02',)]
574的想法是首先按升序对NFV部分进行分类,然后我们也按升序对SWSTO进行分类,但将以“V”结尾的SWSTO放在第一位
我该怎么做呢?
发布于 2020-06-03 06:19:49
若要将排序模式转换为元组,请将“V”的存在视为负无穷大,否则使用数字。
最后,我们可以使用zip和re等Python的便利功能来减少代码行。
import re
from math import inf
def sorted_tuples(string_list):
def rank(chunk):
if 'V' in chunk:
return -inf
return int(re.findall(r"\d+", chunk)[0])
items = [(word, word.split('-')) for (word,) in string_list]
keys = [(word, rank(chunks[1]), rank(chunks[2])) for (word, chunks) in items]
keys.sort(key=lambda x: (x[1], x[2]))
return list(zip(*keys))[0]
print(sorted_tuples([
('site-nfv01-swsto01V',),
('site-nfv01-swsto01',),
('site-nfv01-swsto02',),
('site-nfv02-swsto01V',),
('site-nfv02-swsto01',) ,
('site-nfv02-swsto02',)]))
# Outputs:
# ('site-nfv01-swsto01V',
# 'site-nfv01-swsto01',
# 'site-nfv01-swsto02',
# 'site-nfv02-swsto01V',
# 'site-nfv02-swsto01',
# 'site-nfv02-swsto02'
# )或者,对于一行代码(不要这样做!):
lambda string_list: list(zip(*sorted([(word, list(map(lambda x: -inf \
if 'V' in x else int(re.findall(r"\d+", x)[0]), word.split('-') \
[1:]))) for (word,) in string_list], key=lambda x: x[1])))[0]发布于 2020-06-03 06:38:18
最好的方法是对sorted函数使用key参数。
来自docs
键参数的值应该是接受单个参数并返回用于排序目的的键的函数。这种技术速度很快,因为对每个输入记录只调用一次键函数。
要对您的代码列表进行排序,我会这样做:
your_list = [('site-nfv01-swsto01',), ('site-nfv01-swsto01V',),('site-nfv01-swsto02',),('site-nfv02-swsto02',), ('site-nfv02-swsto01',) , ('site-nfv02-swsto01V',)]
#sort using key parameter
#key must be a function that returns a new value to be sorted
#this particular key function checks if 'V' is at the last position,
#leaves the code unchanged if true,
#else adds arbitrary string at the end of the code that will cause the code to be sorted after codes with the same content at the beginning but lacking the 'V'
#in this case I chose 'z' which comes after 'v' in the alphabet
sorted_list = sorted(your_list, key=lambda code: code[0] if code[0][-1] == 'V' else code[0]+'z')如果您不知道lambda表达式是如何工作的,请查看docs。
发布于 2020-06-03 07:31:48
我发现创建一个独立的键控函数要清晰得多:
#!/usr/bin/env python
lst = [
("site-nfv01-swsto01",),
("site-nfv01-swsto01V",),
("site-nfv01-swsto02",),
("site-nfv02-swsto02",),
("site-nfv02-swsto01",),
("site-nfv02-swsto01V",),
]
def my_key(item):
"""Return a tuple that can be used for ordering the item."""
first, middle, last = item[0].split("-")
# For the middle part, what we really care about is the int after the "nfv" string.
middle_int = int(middle[3:])
# For the last part, we mostly care about the int after the "swsto" string...
last_value = last[5:]
# ...but not quite. Let's make sure that items with a trailing "V" sort lower than ones without
# a "V".
if last_value.endswith("V"):
last_tuple = int(last_value[:-1]), "V"
else:
last_tuple = int(last_value), "z"
# Python sorts tuples one component at a time, so return a tuple that can be compared against
# the tuples generated for other values.
return first, middle_int, last_tuple
# For demonstration purposes, show the sorting key generated for each item in the list.
for item in lst:
print(item, my_key(item))
# Use that sorting key to actually sort the list.
print(sorted(lst, key=my_key))这让您可以非常明确地了解排序键是如何生成的,这大大简化了测试。
https://stackoverflow.com/questions/62162051
复制相似问题