Как отсортировать 2d массив по строкам в python? - PullRequest
16 голосов
/ 01 февраля 2010

У меня есть 2d массив, размер 3x10, и я хочу отсортировать по значениям во 2-й строке, от самого низкого до самого высокого значения.

Ответы [ 5 ]

28 голосов
/ 01 февраля 2010

Как выглядит ваш "2D массив"?

Например:

>>> a = [
     [12, 18, 6, 3], 
     [ 4,  3, 1, 2], 
     [15,  8, 9, 6]
]
>>> a.sort(key=lambda x: x[1])
>>> a
[[4,  3,  1, 2], 
 [15, 8,  9, 6], 
 [12, 18, 6, 3]]

Но я думаю, вы хотите что-то вроде этого:

>>> a = [
     [12, 18, 6, 3], 
     [ 4,  3, 1, 2], 
     [15,  8, 9, 6]
]
>>> a = zip(*a)
>>> a.sort(key=lambda x: x[1])
>>> a
[(6,  1,  9), 
 (3,  2,  6), 
 (18, 3,  8), 
 (12, 4, 15)]
>>> a = zip(*a)
>>> a
[(6, 3, 18, 12), 
 (1, 2,  3,  4), 
 (9, 6,  8, 15)
]
20 голосов
/ 01 февраля 2010

Python сам по себе не имеет «2d-массива» - он имеет (1d) списки в качестве встроенных модулей и (1d) массивы в стандартном библиотечном модуле массив . Существуют сторонние библиотеки, такие как numpy, которые предоставляют многомерные массивы, используемые в Python, но, конечно, вы бы упоминали такие сторонние библиотеки, если использовали некоторые из них, вместо того, чтобы просто сказать «в Python» вправо ? -)

Итак, я предполагаю, что под «2d массивом» вы подразумеваете список списков, например:

lol = [ range(10), range(2, 12), range(5, 15) ]

или тому подобное - то есть список из 3 элементов, каждый из которых представляет собой список из 10 элементов, а "вторая строка" будет элементом списка lol[1]. Да, много предположений, но ваш вопрос настолько безумно расплывчат, что нет никакого способа избежать предположений - отредактируйте свой Q, чтобы прояснить это с большей точностью, и пример! как вы в настоящее время делаете невозможным избежать.

Таким образом, согласно этим предположениям вы можете отсортировать каждый из 3 подсписков в порядке, необходимом для сортировки второго, например:

indices = range(10)
indices.sort(key = lol[1].__getitem__)
for i, sublist in enumerate(lol):
  lol[i] = [sublist[j] for j in indices]

Общий подход здесь состоит в том, чтобы отсортировать диапазон индексов, а затем просто использовать этот соответствующим образом отсортированный диапазон, чтобы изменить порядок всех подсписков в игре.

Если у вас действительно другая проблема, то, конечно, будут другие решения; -).

6 голосов
/ 01 февраля 2010

Вместо использования lambda x: x[1] вы можете использовать operator.itemgetter в качестве ключа для сортировки или сортировки функций. itemgetter (n) создает функцию, которая получает n-й элемент из списка.

>>> matrix = [ [4,5,6], [1,2,3], [7,0,9]]
>>> from operator import itemgetter
>>> sorted(matrix, key=itemgetter(1))
[[7, 0, 9], [1, 2, 3], [4, 5, 6]]
1 голос
/ 01 февраля 2010

Ну, если вы говорите о стандартных списках Python, это просто: mylist[1].sort(). Например:

>>> from random import randint
>>> a_list = [[randint(1,15) for _ in range(10)] for _ in range(3)]
>>> print a_list
[[3, 12, 3, 12, 13, 5, 12, 2, 1, 13], [3, 8, 7, 4, 6, 11, 15, 12, 4, 6], [15, 3, 8, 15, 1, 6, 4, 7, 15, 14]]
>>> a_list[1].sort()
>>> print a_list
[[3, 12, 3, 12, 13, 5, 12, 2, 1, 13], [3, 4, 4, 6, 6, 7, 8, 11, 12, 15], [15, 3, 8, 15, 1, 6, 4, 7, 15, 14]]
0 голосов
/ 20 марта 2013

Это небольшая функция, которую я написал для этой цели:

def sorted_table(data, column=0, reverse=False):
    return sorted(data, cmp=lambda a,b: cmp(a[column], b[column]), reverse=reverse)

На самом деле у меня было немного более сложное требование - сортировать таблицу по двум столбцам. Оказывается, функция cmp() довольно универсальна; это моя оригинальная функция:

def sort_report(data):
    """Sort report columns: first by value, then by label."""
    return sorted(data, cmp=lambda a,b: cmp(b[2], a[2]) or cmp(a[0], b[0])) # label is column 0; value is column 2

В первом случае b и a поменялись местами, поскольку целью было отсортировать значения по убыванию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...