any*_*ny1 2 python sorting string integer list
我有一个字符串列表,可以表示整数和名称.默认字符串比较执行以下操作:
sorted(['1','2','3','4','10','102','14','Alice','John','Sally'])
['1', '10', '102', '14', '2', '3', '4', 'Alice', 'John', 'Sally']
Run Code Online (Sandbox Code Playgroud)
我想按如下方式对列表进行排序:
['1', '2', '3', '4', '10', '14', '102', 'Alice', 'John', 'Sally']
Run Code Online (Sandbox Code Playgroud)
意思是:
我尝试过比较方法,但我不知道如何干净地确定字符串是否代表一个没有try/except的整数?
提前致谢
kin*_*all 10
如果没有负数:
lyst = ['1','2','3','4','10','102','14','Alice','John','Sally']
print sorted(lyst, key=lambda k: int(k) if k.isdigit() else k)
Run Code Online (Sandbox Code Playgroud)
这是一个不依赖于CPython细节并与Python 3一起使用的版本:
sorted(lyst, key=lambda k: (0, int(k)) if k.isdigit() else (1, k))
Run Code Online (Sandbox Code Playgroud)
这里的关键是一个元组.对于数字或文本,元组中的第一项为0或1,这使得数字在文本之前排序.然后元组中的第二个项是值,这会使值在其组内适当地排序.我最初习惯于float("+inf")在文本项之后对数字进行排序,但这种方法(受Tom Zych的回答启发)更简单,更快捷.
如果您希望字符串排序不区分大小写,只需添加.lower():
sorted(lyst, key=lambda k: (0, int(k)) if k.isdigit() else (1, k.lower()))
Run Code Online (Sandbox Code Playgroud)
以下适用于Python 2和Python 3:
l = ['1','2','3','4','10','102','14','Alice','John','Sally','33']
num, alpha = [], []
[num.append(elem) if elem.isdigit() else alpha.append(elem) for elem in l]
result = sorted(num, key=int) + sorted(alpha)
print(result)
Run Code Online (Sandbox Code Playgroud)
它通过分区列表避免了将字符串与int进行比较.避免这种比较的原因是它没有完全指定(Python 2)或禁止(Python 3).
这应该适用于sort具有关键功能的版本.
def sortkey(s):
try:
n = int(s)
return (0, n)
except ValueError:
return (1, s)
Run Code Online (Sandbox Code Playgroud)