以下列方式对字符串列表进行排序的最简单方法是什么?

时间:2011-10-17 15:02:36

标签: 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']

表示:

  1. 对所有以数字方式表示整数的字符串进行排序
  2. 按字母顺序对“真实”字符串进行排序,并将此列表附加到(1。)
  3. 我尝试过比较方法,但我不知道如何干净地确定字符串是否代表一个没有try / except的整数?

    提前致谢

4 个答案:

答案 0 :(得分: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)

这是一个不依赖于CPython细节并与Python 3一起使用的版本:

sorted(lyst, key=lambda k: (0, int(k)) if k.isdigit() else (1, k))

这里的关键是一个元组。对于数字或文本,元组中的第一项为0或1,这使得数字在文本之前排序。然后元组中的第二个项是值,这会使值在其组内适当地排序。我最初使用float("+inf")来使文本项在数字后排序,但这种方法(受Tom Zych的回答启发)更简单,更快。

如果您希望字符串排序不区分大小写,请添加.lower()

sorted(lyst, key=lambda k: (0, int(k)) if k.isdigit() else (1, k.lower()))

答案 1 :(得分:5)

以下适用于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)

它通过对列表进行分区来避免将字符串与int进行比较。避免这种比较的原因是它是not fully specified(Python 2)或禁止(Python 3)。

答案 2 :(得分:5)

这应该适用于具有关键功能的sort版本。

def sortkey(s):
    try:
        n = int(s)
        return (0, n)
    except ValueError:
        return (1, s)

答案 3 :(得分:0)

我会选择比较功能:

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)