我有一個看起來像這樣的(Python)字典:
[
{
"data": "somedata1",
"name": "prefix1.7.9"
},
{
"data": "somedata2",
"name": "prefix1.7.90"
},
{
"data": "somedata3",
"name": "prefix1.1.1"
},
{
"data": "somedata4",
"name": "prefix4.1.1"
},
{
"data": "somedata5",
"name": "prefix4.1.2"
},
{
"data": "somedata5",
"name": "other 123"
},
{
"data": "somedata6",
"name": "different"
},
{
"data": "somedata7",
"name": "prefix1.7.11"
},
{
"data": "somedata7",
"name": "prefix1.11.9"
},
{
"data": "somedata7",
"name": "prefix1.17.9"
}
]
現在我想按“名稱”鍵對其進行排序。如果后綴是數字(被 2 分),我想對它進行數字排序。例如,結果訂單:
different
other 123
prefix1.1.1
prefix1.1.9
prefix1.7.11
prefix1.7.90
prefix1.11.9
prefix1.17.9
prefix4.1.1
prefix4.1.2
你知道如何做這個簡短而有效的嗎?我唯一的想法是建立一個完整的新串列,但也許這也可以使用 lambda 函式來完成?
uj5u.com熱心網友回復:
您可以使用re.findall正則運算式,從每個名稱中提取非數字單詞或數字,并將數字轉換為整數以進行數字比較。為避免字串和整數之間的比較,請將鍵設為元組,其中第一項是標記是否為數字的布林值,第二項是用于比較的實際鍵:
import re
# initialize your input list as the lst variable
lst.sort(
key=lambda d: [
(s.isdigit(), int(s) if s.isdigit() else s)
for s in re.findall(r'[^\W\d] |\d ', d['name'])
]
)
演示:https ://replit.com/@blhsing/ToughWholeInformationtechnology
uj5u.com熱心網友回復:
您需要想出一種從“名稱”值中提取前綴和后綴的方法。這可以使用類似的東西來實作:
import math
def extract_prefix(s: str) -> str:
return s.split('.')[0]
def extract_postfix(s: str) -> float:
try:
return float('.'.join(s.split('.')[1:]))
except ValueError:
# if we cannot form a float i.e. no postfix exists, it'll be before some value with same prefix
return -math.inf
arr = [{'data': 'somedata1', 'name': 'prefix1.7.9'},
{'data': 'somedata2', 'name': 'prefix1.7.90'},
{'data': 'somedata3', 'name': 'prefix1.1.1'},
{'data': 'somedata4', 'name': 'prefix4.1.1'},
{'data': 'somedata5', 'name': 'prefix4.1.2'},
{'data': 'somedata5', 'name': 'other 123'},
{'data': 'somedata6', 'name': 'different'},
{'data': 'somedata7', 'name': 'prefix1.7.11'},
{'data': 'somedata7', 'name': 'prefix1.11.9'},
{'data': 'somedata7', 'name': 'prefix1.17.9'}]
result = sorted(sorted(arr, key=lambda d: extract_postfix(d['name'])), key=lambda d: extract_prefix(d['name']))
result:
[{'data': 'somedata6', 'name': 'different'},
{'data': 'somedata5', 'name': 'other 123'},
{'data': 'somedata3', 'name': 'prefix1.1.1'},
{'data': 'somedata7', 'name': 'prefix1.7.11'},
{'data': 'somedata1', 'name': 'prefix1.7.9'},
{'data': 'somedata2', 'name': 'prefix1.7.90'},
{'data': 'somedata7', 'name': 'prefix1.11.9'},
{'data': 'somedata7', 'name': 'prefix1.17.9'},
{'data': 'somedata4', 'name': 'prefix4.1.1'},
{'data': 'somedata5', 'name': 'prefix4.1.2'}]
uj5u.com熱心網友回復:
由于您想按數字排序,因此您需要一個輔助函式:
def split_name(s):
nameparts = s.split('.')
for i,p in enumerate(nameparts):
if p.isdigit():
nameparts[i] = int(p)
return nameparts
obj = obj.sort(key = lambda x:split_name(x['name']))
uj5u.com熱心網友回復:
在這里,我首先按版本對串列進行排序。存盤在另一個串列 rank 呼叫 rank 中,該串列有助于復制排名位置以進行自定義排序。
代碼使用pkg_resources:
from pkg_resources import parse_version
rank=sorted([v['name'] for v in Mydata], key=parse_version)
或者
rank = sorted(sorted([v['name'] for v in Mydata], key=parse_version), key = lambda s: s[:3]=='pre') #To avoid the prefix value in sorting
sorted(Mydata, key = lambda x: rank.index(x['name']))
輸出:
[{'data': 'somedata6', 'name': 'different'},
{'data': 'somedata5', 'name': 'other 123'},
{'data': 'somedata3', 'name': 'prefix1.1.1'},
{'data': 'somedata1', 'name': 'prefix1.7.9'},
{'data': 'somedata7', 'name': 'prefix1.7.11'},
{'data': 'somedata2', 'name': 'prefix1.7.90'},
{'data': 'somedata7', 'name': 'prefix1.11.9'},
{'data': 'somedata7', 'name': 'prefix1.17.9'},
{'data': 'somedata4', 'name': 'prefix4.1.1'},
{'data': 'somedata5', 'name': 'prefix4.1.2'}]
使用另一個輸入:
[{'data': 'somedata6', 'name': 'Aop'},
{'data': 'somedata6', 'name': 'different'},
{'data': 'somedata5', 'name': 'other 123'},
{'data': 'somedata7', 'name': 'pop'},
{'data': 'somedata3', 'name': 'prefix1.hello'},
{'data': 'somedata3', 'name': 'prefix1.1.1'},
{'data': 'somedata4', 'name': 'prefix1.2.hello'},
{'data': 'somedata1', 'name': 'prefix1.7.9'},
{'data': 'somedata7', 'name': 'prefix1.7.11'},
{'data': 'somedata2', 'name': 'prefix1.7.90'},
{'data': 'somedata7', 'name': 'prefix1.17.9'},
{'data': 'somedata7', 'name': 'prefix1.17.9'},
{'data': 'somedata5', 'name': 'prefix4.1.2'},
{'data': 'somedata7', 'name': 'prefix9.1.1'},
{'data': 'somedata7', 'name': 'prefix10.11.9'}]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/514781.html
標籤:Python算法排序字典
