【问题标题】:Python 3 List: How do I sort [('NJ', 81), ('CA', 81), ('DC', 52)] base on number and then letters?Python 3 列表:如何根据数字和字母对 [('NJ', 81), ('CA', 81), ('DC', 52)] 进行排序?
【发布时间】:2013-07-16 16:52:38
【问题描述】:

如果我的清单是 [('IL', 36), ('NJ', 81), ('CA', 81), ('DC', 52), ('TX', 39)],

我怎样才能对它进行排序,以便我的结果是 [('CA', 81), ('NJ', 81), ('DC', 52), ('TX', 39), ('IL', 36)]?

【问题讨论】:

  • .. 或“如何对 2 元组列表进行排序,从第二个元素降序,然后从第一个元素升序?”

标签: python list sorting python-3.x


【解决方案1】:

如果您不方便使用-somefield,那么 Pythonic 方法将是利用 Python 的稳定排序进行多阶段排序。

a = [('IL', 36), ('NJ', 81), ('CA', 81), ('DC', 52), ('TX', 39)]

from operator import itemgetter
a.sort(key=itemgetter(0))
a.sort(key=itemgetter(1), reverse=True)
# [('CA', 81), ('NJ', 81), ('DC', 52), ('TX', 39), ('IL', 36)]

【讨论】:

    【解决方案2】:

    非常简单:

    your_list.sort(key=lambda e: (-e[1], e[0]))
    

    例如

    >>> your_list = [('IL', 36), ('NJ', 81), ('CA', 81), ('DC', 52), ('TX', 39)]
    >>> your_list.sort(key=lambda e: (-e[1], e[0]))
    >>> your_list
    [('CA', 81), ('NJ', 81), ('DC', 52), ('TX', 39), ('IL', 36)]
    

    请注意,上面对列表进行了适当的排序。如果您想将其包装在一个函数中而不修改原始列表,请使用sorted

    def your_sort(your_list):
        return sorted(your_list, key=lambda e: (-e[1], e[0]))
    

    【讨论】:

      【解决方案3】:

      如果不相等则比较第一个元素,如果相等则比较第二个元素。如果您想要相反的顺序,请将cmp(a, b) 切换为cmp(b, a)

      >>> a = [('IL', 36), ('NJ', 81), ('CA', 81), ('DC', 52), ('TX', 39)]
      >>> sorted(a, cmp=lambda x, y: 
                            cmp(y[1],x[1]) if x[1]!=y[1] else cmp(x[0],y[0]))
      [('CA', 81), ('NJ', 81), ('DC', 52), ('TX', 39), ('IL', 36)]
      

      另一个答案更短,但即使其中一个元素不是数字并且可以扩展到任意数量的级别,这种方法也有效,尽管您可能想要编写一个适当的比较函数而不是使用 lambda - 对于一个泛型N级排序:

      >>> def arbitrary_level_tuple_sort(iterable, order=[(0, 'a')]):
              def comparator(a, b):
                  for i, o in order:
                      if a[i] != b[i]:
                          if o == 'a':
                              return cmp(a[i], b[i])
                          else:
                              return cmp(b[i], a[i])
                  return 0
              return sorted(iterable, cmp=comparator)
      
      >>> arbitrary_level_tuple_sort(a, [(1, 'd'), (0, 'a')])
      [('CA', 81), ('NJ', 81), ('NJ', 81), ('TX', 39), ('IL', 36)]
      

      order 参数是元组索引和顺序的列表 (a=ascending/d=descending),这适用于任何大小的元组:

      >>> b = [tuple([random.randint(0, 10) for i in range(5)]) for i in range(5)]
      >>> b
      [(7, 5, 5, 8, 0),
       (0, 4, 5, 0, 7),
       (7, 4, 0, 9, 0),
       (1, 1, 3, 9, 4),
       (6, 2, 9, 6, 3)]
      

      按第 4 个元素(索引 3)降序排序,然后按第 5 个和第一个升序排序:

      >>> arbitrary_level_tuple_sort(b, [(3, 'd'), (4, 'a'), (0, 'a')])
      [(7, 4, 0, 9, 0),
       (1, 1, 3, 9, 4),
       (7, 5, 5, 8, 0),
       (6, 2, 9, 6, 3),
       (0, 4, 5, 0, 7)]
      

      【讨论】:

        猜你喜欢
        • 2018-09-03
        • 1970-01-01
        • 2018-04-09
        • 2021-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-06
        相关资源
        最近更新 更多