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']
这意味着:

  • 对表示整数的所有字符串进行数字排序
  • 按字母顺序对“真实”字符串排序,并将此列表附加到(1)中
  • 我尝试过使用compare方法,但我不知道如何在没有try/except的情况下清楚地确定字符串是否表示整数


    如果没有负数,请提前感谢

    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(…)
    中使用生成器表达式,而不是列表理解!