【问题标题】:How to sort a multidimensional list to alphabetical order based on its first row letters in python如何根据python中的第一行字母将多维列表按字母顺序排序
【发布时间】:2015-02-05 14:51:18
【问题描述】:

如何在不使用 numpy 或其他模块的情况下根据其第一行数据按字母顺序对多维列表进行排序

例如我有一个列表:

[['M', 'A', 'R', 'K']
[1,    3,   5,    4]
[2,    6,   7,    8]]

我希望它是这样的:

[['A', 'K', 'M', 'R']
[3,    4,   1,    5]
[6,    8,   2,    7]]

谢谢!

【问题讨论】:

  • 你尝试过什么吗?包括您尝试过的内容
  • 我试过像下面的例子那样使用 numy,但我没有找到不使用的解决方案。
  • 这应该是你的问题的一部分,就像你想要的那样,而不使用“nummy”?这会让你清楚地知道你想要什么?谢谢

标签: python arrays algorithm sorting multidimensional-array


【解决方案1】:

我认为应该有更好的方法;无论如何,这可以解决问题:

>>> l = [['M', 'A', 'R', 'K'], [1, 3, 5, 4], [2, 6, 7, 8]]
>>> sorted_l = map(list, zip(*sorted(zip(*l))))
>>> print(list(sorted_l))
[['A', 'K', 'M', 'R'], [3, 4, 1, 5], [6, 8, 2, 7]]

编辑:

  1. zip(*l) 给你一个迭代器(在 Python 3 中),如果你这样做 [i for i in zip(*l)],你会发现它看起来像 [('M', 1, 2), ('A', 3, 6), ('R', 5, 7), ('K', 4, 8)]

  2. sorted(zip(*l)) 对上面的列表进行排序(在后台变成[('A', 3, 6), ('K', 4, 8), ('M', 1, 2), ('R', 5, 7)]),我没有指定键,所以它直接比较元素

  3. 然后,你再次压缩,你会得到一个你想要的迭代器(l 中的元素是('A', 'K', 'M', 'R'), (3, 4, 1, 5), (6, 8, 2, 7),如果你把它们打印出来);但是,您必须使用map(),这样您才能获得<class 'list'> 而不是<class 'tuple'>

  4. 最后,map() 在 Python3 中也返回一个迭代器,要获得一个列表,您只需使用 list([iterable]) 构造最终列表。

文档:zipsortedmap

【讨论】:

    【解决方案2】:

    一旦您知道排序索引的新“顺序”(或映射),您应该能够使用operator.itemgetter 基本上遍历所有行并按照您刚刚找到的顺序获取项目。

    在你的情况下,你有['M', 'A', 'R', 'K']。为了对这些字母进行排序,您应该首先获取索引1,然后是索引3,然后是索引0,最后是索引2(A K M R)。找到该映射后,您只需致电 itemgetter 即可按该顺序为您获取每一行的项目。

    import operator
    a=[
        ['M', 'A', 'R', 'K'],
        [1,    3,   5,    4],
        [2,    6,   7,    8],
    ]
    sorted_first = sorted(a[0])
    sorted_indexes = [a[0].index(letter) for letter in sorted_first]
    print "Mapping: %s" % sorted_indexes
    new_sorted = [operator.itemgetter(* sorted_indexes)(line) for line in a]
    print new_sorted
    

    哪些输出:

    Mapping: [1, 3, 0, 2]
    [('A', 'K', 'M', 'R'),
     (3, 4, 1, 5),
     (6, 8, 2, 7)]
    

    编辑:

    rpatisso 让我看到(在这个答案的 cmets 中)有比使用 list.index 更有效的方法来计算 sorted_indexes 变量,即 O(n2)

    sorted_indexes = sorted(range(len(a[0])), key=lambda i: a[0][i])
    

    【讨论】:

    • 在每个元素的列表中搜索sorted_indexes 的位置并不是很高效 O(n^2)。
    • 4 项列表只是一个例子。
    • 你怎么知道的?而且,根据您的说法,那么什么是更有效的方法?
    • OP 说“例如”,sorted_indices = sorted(range(len(a[0])), key=lambda i: a[0][i]) 将是 O(nlog n),就像接受的答案一样。
    • 该死!你说得对。我试图开始这样做,给了我一些错误......与index一起使用。
    【解决方案3】:

    用 numpy 试试吧。

    >>> import numpy as np
    >>> a = np.array([['M', 'A', 'R', 'K'],
    ... [1,    3,   5,    4],
    ... [2,    6,   7,    8]], dtype=object)
    >>> a[:,np.argsort(a[0])]
    array([['A', 'K', 'M', 'R'],
           [3, 4, 1, 5],
           [6, 8, 2, 7]], dtype=object)
    

    没有 numpy:

    >>> map(list,zip(*sorted(zip(*a))))
    [['A', 'K', 'M', 'R'], [3, 4, 1, 5], [6, 8, 2, 7]]
    

    【讨论】:

    • 有没有办法不使用numpy?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    相关资源
    最近更新 更多