简体   繁体   English

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

[英]lists: index of lowest value and reorder

I have a list like this: 我有一个这样的列表:

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

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

now I want to reorder the entrys this way:: I want to get the index of the a-column where I have the lowest y-value. 现在我想以这种方式重新排序:我希望获得a-column的索引,其中我的y值最低。 let's say, in example, in a3 there is the lowest y-value of all a's. 让我们说,例如,在a3中,所有a的y值都是最低的。 so I want to reorder my list this way: 所以我想以这种方式重新排序我的列表:

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

-> so I don't care about the other y-values, only want to know the lowest one and set this at the first position of my list and keep the sequence (a5 after a4 after a3...) alive -> the values which where in the original list before a3 (a1 and a2) shall appended in the end. - >所以我不关心其他的y值,只想知道最低的值并将其设置在我的列表的第一个位置并保持序列(在a3之后a4之后的a5 ......)活着 - >在a3(a1和a2)之前的原始列表中的位置最后应附加的值。

I know I can get the lowest y-value of the first column with this: 我知道我可以得到第一列的最低y值:

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

But I don't need the value, but the index. 但我不需要值,而是索引。 And how can I reorder my list without a for-loop? 如何在没有for-loop的情况下重新排序列表?

Edit: Reason for not using a for-loop: It's a huge list and I'm looking for a more efficient way. 编辑:没有使用for循环的原因:这是一个巨大的列表,我正在寻找一种更有效的方法。 But I would also accept a for-loop. 但我也会接受一个for循环。

You could find the appropriate index then use a list comprehension: 你可以找到合适的索引然后使用列表理解:

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]

Note that this will loop, but any code you write to do this will at some point! 请注意,这循环,但您编写的任何代码都会在某些时候执行此操作!

You've got a list of lists of lists; 你有一份清单清单; I'm assuming the outer list stays the same. 我假设外部列表保持不变。

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

The main takeaway is to sort with a lambda key, and the min(*x) takes the min of all the values in list x 主要的内容是用lambda键排序, min(*x)取列表x中所有值的min

You have to loop through foo, but that's to be expected. 你必须循环foo,但这是可以预料的。

A numpy based solution. 一个基于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

Or in case you decide you would like to sort the entire row, and don't mind the slightly higher computational load: 或者,如果您决定要对整行进行排序,并且不介意稍高的计算负荷:

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

Either way, both of these will blow a pure python based solution out of the water, in terms of performance. 无论哪种方式,在性能方面,这两者都将从水中吹出纯粹的基于python的解决方案。

Easy: To sort columns by first element, flip along diagonal, sort rows by first element, flip back. 简单:按第一个元素对列进行排序,沿对角线翻转,按第一个元素对行进行排序,然后翻转。

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)

And to prove it works: 并证明它的工作原理:

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)

yields 产量

[[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]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM