lists:最低值索引和重新排序

时间:2014-01-08 21:42:18

标签: python list

我有一个这样的清单:

foo =
[[a1, a2, a3, a4, a5],
 [b1, b2, b3, b4, b5],
 [c1, c2, c3, c4, c5]]
# in real: many more rows & columns

每个a_i,b_i和c_i包含3个值:[x,y,z]

现在我想以这种方式重新排序: 我想获得a列的索引,其中y值最低。让我们说,例如,在a3中,所有a的y值都是最低的。 所以我想以这种方式重新排序我的列表:

[[a3, a4, a5, a1, a2],
 [b3, b4, b5, b1, b2],
 [c3, c4, c5, c1, c2]]

- >所以我不关心其他的y值,只想知道最低的值,并将其设置在我的列表的第一个位置,并保持序列(a3之后a4之后的a5 ......)活着 - > a3(a1和a2)之前的原始列表中的位置最后应附加的值。

我知道我可以用这个得到第一列的最低y值:

xmin, ymin, zmin = map(min, zip(*foo[0]))
print ymin

但我不需要值,而是索引。如何在没有for-loop的情况下重新排序我的列表?

编辑: 不使用for循环的原因: 这是一个巨大的列表,我正在寻找一种更有效的方式。但我也会接受一个for循环。

4 个答案:

答案 0 :(得分:2)

您可以找到合适的索引,然后使用列表解析:

from operator import itemgetter

# first get index from first row
min_index = min(enumerate(foo[0]), key=lambda x: x[1][1])[0]

# then apply to all rows
foo = [item[min_index:] + item[:min_index] for item in foo]

请注意,此循环,但您编写的任何代码都会在某个时候执行此操作!

答案 1 :(得分:0)

你有一份清单清单;我假设外部名​​单保持不变。

for row in foo:
    row.sort(key=lambda x:min(*x))

主要内容是使用lambda键进行排序,min(*x)获取列表x中所有值的最小值

你必须遍历foo,但这是可以预期的。

答案 2 :(得分:0)

基于numpy的解决方案。

import numpy as np
foo = np.random.randint(0,100,(3,5))    #some random data for testing
print foo                               #original order
i = np.argmin(foo[1,:])                 #find min index of second row
foo[:,[0,i]] = foo[:,[i,0]]             #swap columns to move selected row to front
print foo                               #new order

或者,如果您决定要对整行进行排序,并且不介意稍高的计算负荷:

import numpy as np
foo = np.random.randint(0,100,(3,5))    #some random data for testing
print foo                               #original order
foo = foo[:,np.argsort(foo[1])]         #complete sorting by second row
print foo                               #new order

无论哪种方式,这两种方法都会在性能方面将纯粹的基于python的解决方案从水中吹出来。

答案 3 :(得分:0)

简单:按第一个元素对列进行排序,沿对角线翻转,按第一个元素对行进行排序,然后翻转。

def diagFlip(grid):
    return [[grid[i][j] for i in range(len(grid))] for j in range(len(grid[0]))]

def sortByColumnTops(grid):
    grid = diagFlip(grid)
    grid.sort(key=(lambda row: row[0][1]))
    return diagFlip(grid)

并证明它有效:

test = [[[0,4,0],[0,2,0],[0,3,0],[0,1,0]],
        [[0,1,0],[0,3,0],[0,2,0],[0,4,0]],
        [[0,1,0],[0,2,0],[0,3,0],[0,4,0]]]
test = sortByColumnTops(test)

for row in test: print(row)

产量

[[0, 1, 0], [0, 2, 0], [0, 3, 0], [0, 4, 0]]
[[0, 4, 0], [0, 3, 0], [0, 2, 0], [0, 1, 0]]
[[0, 4, 0], [0, 2, 0], [0, 3, 0], [0, 1, 0]]