Python 按以下方式对字符串列表排序的最简单方法是什么?
我有一个字符串列表,可以表示整数和名称。 默认字符串比较执行以下操作:Python 按以下方式对字符串列表排序的最简单方法是什么?,python,string,list,sorting,integer,Python,String,List,Sorting,Integer,我有一个字符串列表,可以表示整数和名称。 默认字符串比较执行以下操作: sorted(['1','2','3','4','10','102','14','Alice','John','Sally']) ['1', '10', '102', '14', '2', '3', '4', 'Alice', 'John', 'Sally'] 我想把清单分类如下: ['1', '2', '3', '4', '10', '14', '102', 'Alice', 'John', 'Sally'] 这意味着
sorted(['1','2','3','4','10','102','14','Alice','John','Sally'])
['1', '10', '102', '14', '2', '3', '4', 'Alice', 'John', 'Sally']
我想把清单分类如下:
['1', '2', '3', '4', '10', '14', '102', 'Alice', 'John', 'Sally']
这意味着:
如果没有负数,请提前感谢:
lyst = ['1','2','3','4','10','102','14','Alice','John','Sally']
print sorted(lyst, key=lambda k: int(k) if k.isdigit() else k)
以下是一个不依赖于CPython详细信息并与Python 3配合使用的版本:
sorted(lyst, key=lambda k: (0, int(k)) if k.isdigit() else (1, k))
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)
这里的关键是一个元组。对于数字或文本,元组中的第一项是0或1,这会导致数字在文本之前排序。然后,元组中的第二项是值,这会使值在其组中进行适当排序。我最初使用float(“+inf”)
使文本项按数字排序,但这种方法(受Tom Zych答案的启发)更简单、更快
如果希望字符串排序不区分大小写,只需添加.lower()
:
以下内容适用于Python 2和Python 3:
sorted(lyst, key=lambda k: (0, int(k)) if k.isdigit() else (1, k))
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)
它通过对列表进行分区来避免将字符串与int进行比较。避免这种比较的原因是它要么是(Python2)要么是禁止的(Python3)。这应该适用于采用键函数的
sort
版本
def sortkey(s):
try:
n = int(s)
return (0, n)
except ValueError:
return (1, s)
我将使用比较函数:
import types
def cmp_func(val1, val2):
# is val1 an integer?
try:
val1 = int(val1)
except ValueError:
pass # val1 is no integer
try:
val2 = int(val2)
except ValueError:
pass #val2 is no integer
if type(val1) == types.IntType and type(val2) == types.IntType:
return cmp(val1, val2)
elif type(val1) == types.StringType and type(val2) == types.IntType:
# firstly strings, afterwards integer values
return -1
elif type(val1) == types.IntType and type(val2) == types.StringType:
# firstly strings, afterwards integer values
return 1
else:
return cmp(val1, val2)
if __name__ == "__main__":
my_list = ['1', '10', '102', '14', '2', '3', '4', 'Alice', 'John', 'Sally']
my_list.sort(cmp_func)
print(my_list)
谢谢,这正是我需要的!(在我的例子中没有出现负数)注意:(1)依赖于CPtyhon的实现细节(int在字符串之前比较,而不是在字符串之后比较);(2) 不适用于Python3,因为不允许将int与字符串进行比较;比较第一项;如果它们相同,则比较第二项,依此类推。非常好。为了使Python3能够工作,对于整数返回
(0,n,“”)
,对于字符串返回(1,0,s)
。我喜欢这也适用于负数。然而,它可以用浮点数产生不正确的结果。@StevenRumbalski:OP确实说了“整数”。当然,如果有浮动,我们需要为它们添加一个试转换。我的代码如3.1中所述正常工作;“你为什么认为你的改变是必要的?”汤姆。您是对的,我认为元组的第二个值在Python3上进行整数到字符串比较时会失败,但是我看到它会比较第一个值,而不是第二个值,除非第一个值相同。所以别客气。我喜欢它在2和3上工作。我不喜欢用布尔值进行下标,因为这很容易避免。如果elem.isdigit()或alpha.append(elem)表示l中的elem,我会将列表comp更改为[num.append(elem)]
。它还允许你剪一行。聪明,向上投票。您可以通过在any(…)
中使用列表理解来避免创建None
列表。或者,也就是说,在any(…)
中使用生成器表达式,而不是列表理解!