這個寫法常出現在 `sorted()` 或 `.sort()` 的 `key=` 參數中:
sorted(items, key=lambda x: (-len(x), x))它的目的很簡單:
1. 先讓較長的字串排在前面。
2. 如果字串長度相同,再用字母順序做穩定排序。
這是一種「複合排序鍵」(composite sort key)。
—
## 1. 為什麼不是直接用 `len(x)`?
因為 `sorted()` 預設是由小到大排序。
如果你寫:
sorted(items, key=len)結果會是:
– 短的先排
– 長的後排
但很多情境下,我們想要:
– 完整 Class Name 先出現
– 再來才是 bigram
– 最後才是短 token
所以會把長度取負號:
-len(x)例如:
– `len(“check”) = 5` -> `-5`
– `len(“pcie_check”) = 10` -> `-10`
– `len(“gsyspciecheckprocessstep”) = 24` -> `-24`
排序時因為 `-24 < -10 < -5`,所以就會變成:
– 最長的先排
– 最短的後排
—
## 2. 後面的 `x` 是做什麼?
這一段:
(-len(x), x)不是一個值,而是一個 tuple。
Python 比 tuple 的規則是:
1. 先比第一個元素
2. 如果第一個元素相同,再比第二個元素
所以:
key=lambda x: (-len(x), x)等於:
1. 先按長度由長到短排序
2. 長度相同時,再按字串本身的字母順序排序
這樣的好處是:
– 可讀性好
– 順序穩定
– 每次輸出 deterministic
—
## 3. 直接看範例
items = [
"check",
"pcie",
"gsys",
"pcie_check",
"gsys_pcie",
"GsysPcieCheckProcessStep",
]
result = sorted(items, key=lambda x: (-len(x), x))
print(result)輸出:
解釋:
– `GsysPcieCheckProcessStep` 最長,所以排第一
– `gsys_pcie` 和 `pcie_check` 會先排在較短字串前面,因為它們都比 `check`、`gsys`、`pcie` 長
– `gsys` 和 `pcie` 長度相同,這時才再按字母順序排,所以會是 `gsys` -> `pcie`
– `check` 會排在 `gsys`、`pcie` 前面,是因為它長度比較長,不是因為字母順序
—
## 4. 這和 `reverse=True` 有什麼不同?
很多人會寫:
sorted(items, key=len, reverse=True)這只能做到:
– 長的排前面
但做不到:
– 長度相同時再穩定按字母排序
例如同樣長度的元素,順序可能只是沿用原本輸入順序,不一定是你想要的人類可讀順序。
所以:
sorted(items, key=lambda x: (-len(x), x))通常比:
sorted(items, key=len, reverse=True)更適合做「穩定輸出」。
—
## 5. 什麼情況適合用?
很適合這種資料:
– 完整 class name
– bigram
– token
– 需要 deterministic 輸出的檢查 JSON
例如:
– `class_name_tokenized_lower`
– `class_name_bigram`
– `intersection_tokens`
– `intersection_bigrams`
這些欄位如果希望:
– 完整名稱先看見
– 較長片段優先
– 產出順序固定
那麼 `(-len(x), x)` 很適合。
—
## 6. 什麼情況不適合?
不適合拿去排「自然語料順序本身有意義」的欄位。
例如:
– `docx_body_tokens_lower`
– `docx_body_tokens_lower_clean`
– `body`
因為這些欄位保留的是原始語料的先後順序。
如果你硬排序,雖然 diff 可能更穩定,但語料原貌就被破壞了。
所以一個實務原則是:
1. 結構化 token / bigram 欄位:可以排序
2. 自然語料欄位:不要排序
—
## 7. 小結
`(-len(x), x)` 的意思是:
1. 先按字串長度由長到短排
2. 長度相同時再按字母順序排
它特別適合需要「人類可讀 + 穩定輸出」的結構化字串清單。
最常見寫法:
sorted(items, key=lambda x: (-len(x), x))如果要原地排序:
items.sort(key=lambda x: (-len(x), x))## 8. 一行記法
可以把它記成:
> 長的先,若一樣長,再照字母排。
推薦hahow線上學習python: https://igrape.net/30afN