Python 里的 `‘‘.join(sorted(s))` 到底是什么意思?

Python 里的 `‘‘.join(sorted(s))` 到底是什么意思?

刷 LeetCode 的时候,经常会看到这样一行代码:

key=''.join(sorted(s))

第一次看到这行代码,很多人都会愣一下:

“这什么东西?空字符串、join、sorted,怎么还三件套组合技?”

别急,这行代码其实不难。它的作用一句话概括就是:

把字符串里的字符按顺序排序,然后重新拼成一个新的字符串。


一、先看一个例子

假设有一个字符串:

s="eat"

执行:

key=''.join(sorted(s))

最后得到:

key="aet"

也就是说,"eat"被重新排序成了"aet"


二、拆开来看

这行代码可以拆成两步:

sorted(s)

和:

''.join(...)

三、第一步:sorted(s)

sorted()的作用是排序。

如果:

s="eat"

那么:

sorted(s)

结果是:

['a','e','t']

注意,这里有一个很关键的点:

sorted(s)返回的是列表,不是字符串。

也就是说,它不是返回:

"aet"

而是返回:

['a','e','t']

Python 的意思大概是:

“我已经帮你排好队了,但我先按列表形式给你。”


四、第二步:''.join(...)

既然sorted(s)返回的是列表,那我们就要把这个列表重新拼成字符串。

这时候就要用:

''.join(['a','e','t'])

结果是:

"aet"

这里的''是空字符串,表示字符之间不加任何东西,直接拼接。

比如:

''.join(['a','e','t'])

得到:

"aet"

如果你写成:

'-'.join(['a','e','t'])

得到的就是:

"a-e-t"

如果你写成:

' '.join(['a','e','t'])

得到的就是:

"a e t"

所以:

''.join(...)

意思就是:用空字符串把里面的字符连接起来。


五、完整过程

还是看这个例子:

s="eat"key=''.join(sorted(s))

执行过程是:

sorted("eat")

得到:

['a','e','t']

然后:

''.join(['a','e','t'])

得到:

"aet"

所以最终:

key="aet"

六、它在字母异位词分组里有什么用?

在“字母异位词分组”这道题里,这行代码非常关键。

所谓字母异位词,就是几个字符串使用的字母完全一样,只是顺序不同。

比如:

"eat""tea""ate"

这三个字符串就是字母异位词。

它们原本长得不一样:

eat tea ate

但是一排序,全都变成:

"aet"

代码验证一下:

print(''.join(sorted("eat")))print(''.join(sorted("tea")))print(''.join(sorted("ate")))

输出:

aet aet aet

这就说明,它们可以用同一个key表示。


七、为什么可以用它作为字典的 key?

字典分组时,我们需要一个“统一标识”。

比如:

groups[key].append(s)

如果:

s="eat"

那么:

key="aet"

于是:

groups["aet"].append("eat")

如果:

s="tea"

排序后:

key="aet"

于是:

groups["aet"].append("tea")

如果:

s="ate"

排序后还是:

key="aet"

于是:

groups["aet"].append("ate")

最后就会得到:

{"aet":["eat","tea","ate"]}

这就是字母异位词分组的核心思想。


八、再看完整代码

importcollectionsfromtypingimportListclassSolution:defgroupAnagrams(self,strs:List[str])->List[List[str]]:groups=collections.defaultdict(list)forsinstrs:key=''.join(sorted(s))groups[key].append(s)returnlist(groups.values())

其中最核心的一句就是:

key=''.join(sorted(s))

它负责把不同顺序的字母异位词变成同一个标准形式。


九、容易误解的地方

误解一:sorted(s)会直接返回字符串

不会。

sorted("eat")

返回的是:

['a','e','t']

所以才需要:

''.join(...)

误解二:join是随便用的

join只能拼接字符串序列。

比如下面这样是可以的:

''.join(['a','e','t'])

但如果列表里是数字:

''.join([1,2,3])

会报错。

因为数字不能直接被join拼接,必须先转成字符串。


误解三:''没意义

这里的''很重要。

它表示用什么东西把字符连接起来。

''.join(['a','e','t'])

结果是:

"aet"
'-'.join(['a','e','t'])

结果是:

"a-e-t"

所以''不是摆设,它决定了拼接时中间加什么。


十、总结

key=''.join(sorted(s))

可以拆成两步理解:

第一步:

sorted(s)

把字符串里的字符排序,得到字符列表。

第二步:

''.join(...)

把字符列表重新拼成字符串。

所以:

''.join(sorted("eat"))

结果是:

"aet"

它常用于字母异位词分组,因为:

"eat"->"aet""tea"->"aet""ate"->"aet"

不同顺序的单词,排序后会变成同一个字符串。

一句话记住:

''.join(sorted(s))就是把字符串变成“按字母排序后的标准形态”。