Найти минимальное значение в массиве › 0

Я ищу наименьшее положительное значение в массиве и его позицию в списке. Если значение в списке дублируется, интерес представляет только ПЕРВЫЙ экземпляр. Это то, что у меня есть, делает то, что я хочу, но включает 0.

print "Position:", myArray.index(min(myArray))
print "Value:", min(myArray)

например, как есть, если

myArray = [4, 8, 0, 1, 5]

затем Позиция: 2, Значение: 0

Я хочу, чтобы он представлял позицию: 3, значение: 1


person user3001499    schedule 15.01.2015    source источник
comment
Можете ли вы получить повторяющиеся значения в своем массиве? Если да, вас интересует только позиция первой инстанции?   -  person Mike P    schedule 15.01.2015
comment
дубликаты очень возможны, и да, первый экземпляр представляет интерес, спасибо за указание на это, вопрос будет изменен   -  person user3001499    schedule 15.01.2015
comment
Меня смущает описание проблемы: в нем говорится: «Я ищу минимальное значение в массиве, которое больше 0, и его соответствующую позицию», что для меня читается так, как будто задача состоит в том, чтобы найти наименьшее значение, которое больше, чем ноль и больше, чем его соответствующая позиция. Я предполагаю, что на самом деле это означает найти наименьшее значение (и его положение), которое больше нуля...   -  person Frerich Raabe    schedule 15.01.2015
comment
Имейте в виду, что все решения, приведенные ниже, потерпят неудачу, если в списке нет элементов, превышающих 0.   -  person thefourtheye    schedule 15.01.2015


Ответы (5)


Вы можете использовать выражение генератора с min. Это установит m в качестве минимального значения в a, которое больше 0. Затем он использует list.index для поиска индекса первого появления этого значения.

a = [4, 8, 0, 1, 5]

m = min(i for i in a if i > 0)

print("Position:", a.index(m))
print("Value:", m)
# Position: 3
# Value: 1
person Ffisegydd    schedule 15.01.2015
comment
@ user3001499 Меня смутила формулировка вашего вопроса, и я добавил комментарий, чтобы объяснить свое замешательство. - person Frerich Raabe; 15.01.2015
comment
В худшем случае это решение требует обхода a дважды (если наименьшее значение находится в конце списка). - person Frerich Raabe; 15.01.2015
comment
Да, честно говоря, если бы я принимал, я бы принял нижеприведенный ответ thefourtheye (именно поэтому я проголосовал за него). @user3001499 user3001499 Я бы посоветовал вам использовать решение thefourtheye (и не будет плохо, если вы не примете меня за него :)) - person Ffisegydd; 15.01.2015
comment
@Ffisegydd Я новичок в python, и мне посоветовали избегать лямбда-выражений, пока я не буду более уверен в использовании языка, поэтому спасибо за совет, но пока я буду использовать ваш ответ. - person user3001499; 15.01.2015
comment
помните, что этот метод вызовет ошибку ValueError, если ни один из членов списка a не больше нуля - person Thruston; 08.04.2021

Вы можете использовать функцию min и функцию enumerate, например

result = min(enumerate(a), key=lambda x: x[1] if x[1] > 0 else float('inf'))
print("Position : {}, Value : {}".format(*result)
# Position : 3, Value : 1

Это гарантирует, что если значение больше 0, то использовать это значение для сравнения минимального значения, в противном случае использовать максимально возможное значение (float('inf')).

Поскольку мы итерируем вместе с фактическим индексом элементов, нам не нужно находить фактический индекс с помощью другого цикла.

person thefourtheye    schedule 15.01.2015
comment
первый раз, когда я вижу использование enumerate таким образом, отличный совет! - person markcial; 15.01.2015
comment
Голосую за это, потому что это первое использование enumerate (что позволяет избежать двойного обхода a). - person Frerich Raabe; 15.01.2015
comment
Голосование за использование ключевого параметра для функции min - вместо циклического выполнения с помощью генератора. - person neil; 15.01.2015

Вот еще один способ сделать это с помощью выражения генератора. Обратите внимание, как значения из enumerate (a и b) меняются местами в кортеже для правильной сортировки.

value,position = min(((b,a) for a,b in enumerate(myArray) if b>0), default=(None,None))

Аргумент по умолчанию будет возвращен, когда выражение генератора ничего не возвращает (т. е. нет элементов больше 0). По умолчанию можно установить любое значение, имеющее смысл в логике окружающей программы — здесь возврат None позволит вам протестировать либо if value:, либо if position:.

person neil    schedule 15.01.2015
comment
Это следует принять, это более Pythonic и быстрее, чем другие ответы. - person petabyte; 04.07.2016
comment
Было бы неплохо, если бы он допускал случаи, когда нет значения ›0. - person EL_DON; 04.11.2016
comment
@EL_DON, как насчет этого? Я попробовал несколько более неуклюжих методов, прежде чем понял, что min имеет аргумент по умолчанию. - person neil; 04.11.2016
comment
В моей версии нет аргумента по умолчанию для min. Хотя, похоже, хорошее решение. Кроме того, я обнаружил, что если я правильно формирую свои входные данные, я не сталкиваюсь с проблемой. Представьте себе, что. - person EL_DON; 04.11.2016
comment
@EL_DON кажется, что это было добавлено в 3.4 - person neil; 05.11.2016

добавьте фильтр, затем:

myArray = [4, 8, 0, 1, 5]
result = min(filter(lambda x: x > 0, myArray))
print result # 1
print myArray.index(result) # 3
person markcial    schedule 15.01.2015
comment
Это дает только самое низкое значение; он не дает позицию в массиве. - person Mike P; 15.01.2015

сложный/алгоритмический способ:

int min = array[0], i = 1
list smallest //list of indexes of the smallest element 

// find the first element greater than 0
while (min <= 0 and i < array.length) {
    min = array[i]
    i++
}

// find the first instance of the smallest element greater than 0
while (i < array.length) {
    if (array[i] < min and array[i] > 0) {
        clear the list
        min = array[i]
        list.append(i)
    }
    else if (array[i] == min) {
        list.append(i)
    }
    i++;
}

первый экземпляр наименьшего элемента больше 0 теперь является первым элементом, который вы добавили в список.

edit: у вас также будет список всех индексов с наименьшим значением. Некоторые простые проверки могут сказать вам, нет ли в массиве элементов больше 0, или список пуст и т. д.

person JHaps    schedule 15.01.2015
comment
Я бы сказал, что использование for более питонично, чем использование while, особенно в этой ситуации. Также, если вам нужен индекс и значение, перечисление - это путь, как указано в ответе на четыре глаза. - person bwagner; 15.01.2015
comment
Правда, я оставлю ответ как есть, однако. Для всех, кто интересуется, почему это так, ознакомьтесь с этим: заголовок stackoverflow.com/questions/920645/ - person JHaps; 15.01.2015