【问题标题】:Sorting python list to make letters come before numbers排序python列表以使字母排在数字之前
【发布时间】:2015-03-31 16:36:42
【问题描述】:

我对 python 很陌生,我正在寻找一种方法来对列表进行排序,将单词放在数字之前。

我了解您可以使用 sort 执行以下操作:

a = ['c', 'b', 'd', 'a']
a.sort()
print(a)
['a', 'b', 'c', 'd']

b = [4, 2, 1, 3]
b.sort()
print(b)
[1, 2, 3, 4]

c = ['c', 'b', 'd', 'a', 4, 2, 1, 3]
c.sort()
print(c)
[1, 2, 3, 4, 'a', 'b', 'c', 'd']

但是我想对c 进行排序以生成:

['a', 'b', 'c', 'd', 1, 2, 3, 4]

提前致谢

【问题讨论】:

  • 警告:您的第三个示例在 Python 3 中不起作用。相反,您将得到 TypeError: unorderable types: int() < str()

标签: python sorting


【解决方案1】:

您可以提供一个自定义的 key 参数,它为字符串提供的值低于为整数提供的值:

>>> c = ['c', 'b', 'd', 'a', 4, 2, 1, 3]
>>> c.sort(key = lambda item: ([str,int].index(type(item)), item))
>>> c
['a', 'b', 'c', 'd', 1, 2, 3, 4]

【讨论】:

  • [0, 1][type(item) == int]
  • 如果列表中存在strint 以外的类型,则返回IndexError 失败。
  • @dawg,真的。如果您想要更多类型,可以将它们添加到[str, int] 列表中。或者你甚至可以用lambda item: ({str:0, int:1}.get(type(item), 2), item) 替换它,然后让所有非字符串非整数排序到右边。
  • 这与 Python 的多态性不一致:您应该允许任何行为类似于 int 的对象被视为一个对象,而不是通过使用 type 强制它是一个对象 - 使用 isinstance而是允许一致地对待派生类。
【解决方案2】:

默认的 Python 排序是asciibetical

给定:

>>> c = ['c', 'b', 'd', 'a', 'Z', 0, 4, 2, 1, 3]

默认排序为:

>>> sorted(c)
[0, 1, 2, 3, 4, 'Z', 'a', 'b', 'c', 'd']

它在 Python3 上也完全不起作用:

Python 3.4.3 (default, Feb 25 2015, 21:28:45) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> c = ['c', 'b', 'd', 'a', 'Z', 0, 4, 2, 1, 3]
>>> sorted(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()

解决方案是创建一个元组,其中索引整数作为第一个元素(基于项目类型),项目本身作为下一个元素。 Python 2 和 3 将对具有第二个元素异构类型的元组进行排序。

给定:

>>> c = ['c', 'b', 'd', 'a', 'Z', 'abc', 0, 4, 2, 1, 3,33, 33.333]

注意字符、整数、字符串、浮点数的混合

def f(e):
    d={int:1, float:1, str:0}
    return d.get(type(e), 0), e

>>> sorted(c, key=f)   
['Z', 'a', 'abc', 'b', 'c', 'd', 0, 1, 2, 3, 4, 33, 33.333]

或者,如果你想要一个 lambda:

>>> sorted(c,key = lambda e: ({int:1, float:1, str:0}.get(type(e), 0), e)))  
['Z', 'a', 'abc', 'b', 'c', 'd', 0, 1, 2, 3, 4, 33, 33.333]

根据“狼”的评论,你也可以这样做:

>>> sorted(c,key = lambda e: (isinstance(e, (float, int)), e))
['Z', 'a', 'abc', 'b', 'c', 'd', 0, 1, 2, 3, 4, 33, 33.333]

我必须同意的更好......

【讨论】:

  • 这与 Python 的多态性不一致:您应该允许任何行为类似于 int 的对象被视为一个对象,而不是通过使用 type 强制它是一个对象 - 使用 isinstance而是允许一致地对待派生类。
【解决方案3】:
[sorted([letter for letter in c if isinstance(letter, str)]) + \
 sorted([number for number in c if isinstance(number, int)]]

应该这样做。

【讨论】:

  • 是的,现在还早,我还没有喝咖啡,所以我假设这些数字也在引号中:|但现在已经修好了。
【解决方案4】:

假设我们有一个这样的混合列表:

c = ['s', 'a',2 , 'j', 9, 'e', 11, 't', 'k', 12, 'q']

首先,我们需要将列表分成两个单独的部分(字符串和整数),分别对它们进行排序,然后将它们附加到最后。这是一种方法:

>>> c = sorted([i for i in c if not str(i).isdigit()]) + sorted([i for i in c if str(i).isdigit()])

现在你得到:

>>> c
['a', 'e', 'j', 'k', 'q', 's', 't', 2, 9, 11, 12]

【讨论】:

    【解决方案5】:

    如果您有一个混合 ascii 和数字类型的列表,您需要确定什么是 numeric 对象类型。您可以使用Numbers抽象基类来确定什么是数字(int, float, long, complex)类的实例,包括所有派生类(bool, Decimal, Franctions等):

    >>> from numbers import Number
    >>> [isinstance(n, Number) for n in (0,1.1,0j,True,'a')]
    [True, True, True, True, False]
    

    一旦您知道什么是数字的实例,您就可以使用 Python 布尔创建一个主排序键,列表项本身作为辅助键(即,由 [(True, 1.1), (False, 'abc'), etc] 组成的元组)False 将排序在典型的升序排序中低于True 0

    以将其应用于您的列表(扩展)为例:

    >>> c = ['c', 'b', 'd', 'a', 4, 2, 1, 35, 1.1, 6L, 'aac', True]
    >>> sorted(c, key=lambda e: (isinstance(e, Number), e))
    ['a', 'aac', 'b', 'c', 'd', 1, True, 1.1, 2, 4, 6L, 35]
    

    请注意,不同的数字类型正在正确排序 (1&lt;=True&lt;1.1&lt;6L&lt;35)

    【讨论】:

      【解决方案6】:

      您也可以使用cmp 参数:

      c = ['c', 'b', 'd', 'a', 4, 2, 1, 3]
      
      def compare_function(a, b):
          if isinstance(a, str) and isinstance(b, int):
              return -1
          if isinstance(a, int) and isinstance(b, str):
              return 1
          return cmp(a, b)
      
      c.sort(cmp=compare_function)
      

      【讨论】:

      • em...cmp 有点过时了。但您始终可以通过functools.cmp_to_key 将 cmp 函数转换为键。
      猜你喜欢
      • 1970-01-01
      • 2023-03-20
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 2015-12-09
      • 2014-10-08
      相关资源
      最近更新 更多