简体   繁体   English

从列表中查找“ n”个最小值及其索引

[英]Find 'n' minimum values and their indices from list of lists

I have a list of lists in python: 我在python中有一个列表列表:

final_distances=[[10,21,1,5,0],[10,2,1,5,0],[3,21,1,5,0]]

How do I find the 'n'(consider n =3) minimum values and indices of each list? 如何找到每个列表的'n'(考虑n = 3)个最小值和索引?

Expected Output: 预期产量:

minimum_values=[[0, 1, 5], [0, 1, 2], [0, 1, 3]]

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

This is what I've tried so far... 到目前为止,这是我尝试过的...

new_distances=copy.deepcopy(final_distances)
k=3
for list1 in new_distances:
    min_list =[]
    min_index=[]
    for i in range(0, k):     
        min1 = 9999999;
        for j in range(len(list1)):       
            if list1[j]<min1: 
                min1 = list1[j]          
        min_list.append(min1)
        list1.remove(min1)

I am able to find the minimum values but am not able to keep track of the indices... 我能够找到最小值,但无法跟踪索引...

You can simply use enumerate(iterable) and zip(iterables) to get to what you want: 您可以简单地使用enumerate(iterable)zip(iterables)来获得所需的内容:

def get_min_N_nums_and_indexes_from_inner(l, N=3):
    for inner in l:
        # sort each lists enumeration so you have (index,value) to begin with
        #     use the value as key to sort
        # take first N
        s = sorted(enumerate(inner), key=lambda x:x[1])[:N]
        # seperate values from indexes using zip
        z_idx, z_value = map(list, zip(*s))
        # yield each tuple of (values,indexes)
        yield ( z_value,z_idx )

Test: 测试:

final_distances=[[10,21,1,5,0],[10,2,1,5,0],[3,21,1,5,0]]

k = list( get_min_N_nums_and_indexes_from_inner(final_distances))

for nr,(value,idx) in enumerate(k):
    print( f"{final_distances[nr]} ==> min values {value} -- min index {idx}")

Output: 输出:

[10, 21, 1, 5, 0] ==> min values [0, 1, 5] -- min index [4, 2, 3]
[10, 2, 1, 5, 0] ==> min values [0, 1, 2] -- min index [4, 2, 1]
[3, 21, 1, 5, 0] ==> min values [0, 1, 3] -- min index [4, 2, 0] 

You can use .index() to retrieve the index of an element from a list. 您可以使用.index()从列表中检索元素的索引。

for list1 in new_distances:
    min_list =[]
    min_index=[]

    cpList = copy.copy(list1)  # create a temporary list so that we can reference the original list1 index later on  
                               # a shallow copy will work with 1D lists

    for i in range(0, k):     
        min1 = 9999999;
        for j in range(len(cpList)):    # note that I changed list1 to cpList  
            if cpList[j]<min1:          # as I don't want to modify the original
                min1 = cpList[j]        
        min_list.append(min1)

        ind = list1.index(min1)  # place this before `.remove()`
        min_index.append(ind)    # or else min1 might not be found

        cpList.remove(min1)      # `list1.remove()` will modify your `new_distances` in place
                                 # which is one reason why we did a copy before
                                 # so we use cpList instead
    print(f'List: {min_list}; Index: {min_index}')

Output: 输出:

List: [0, 1, 5]; Index: [4, 2, 3]
List: [0, 1, 2]; Index: [4, 2, 1]
List: [0, 1, 3]; Index: [4, 2, 0]

On another note, you could simplify this part of your code: 另外,您可以简化代码的这一部分:

min1 = 9999999;
for j in range(len(cpList)):       
    if cpList[j]<min1: 
        min1 = cpList[j]  

into

min1 = min(cpList)

by using the min() built-in function which can find the minimum from a list. 通过使用min()内置函数可以从列表中找到最小值。

You also don't need 你也不需要

new_distances=copy.deepcopy(final_distances)

as you'll only need to perform lookup and will copy individual sublists in the loop. 因为您只需要执行查找,并将在循环中复制单个子列表。 So you can remove it unless you have other plans in mind. 因此,除非您有其他计划,否则可以将其删除。

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

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