В Python, как я могу найти индекс первого объекта в списке, который НЕ является некоторым значением?

Тип списка Python имеет индексный (x) метод. Это берет единственный параметр x и возвращает (целочисленный) индекс первого объекта в списке, который имеет значение x.

В основном я должен инвертировать индексный (x) метод. Я должен получить индекс первого значения в списке, который НЕ имеет значения x. Я, вероятно, смог бы даже только к использованию функция, которая возвращает индекс первого объекта со значением! = Ни один.

Я могу думать 'для' реализации цикла с переменной счетчика постепенного увеличения, но я чувствую, что пропускаю что-то. Существует ли существующий метод или короткая конструкция Python, которая может обработать это?

В моей программе подходит ситуация, когда я обрабатываю списки, возвращенные из комплекса regex соответствия. У всех кроме одного объекта в каждом списке есть значение Ни одного. Если бы мне просто была нужна совпавшая строка, то я мог бы использовать понимание списка как' [x для x в [my_list], если x не Ни один]', но мне нужен индекс для выяснения, какая группа получения в моем regex на самом деле вызвала соответствие.

16
задан Ryan B. Lynch 30 April 2010 в 23:35
поделиться

5 ответов

Выйти при первом совпадении очень просто: вместо вычисления полного понимания списка (затем отбрасывая все, кроме первого элемента), используйте next по генэксп. Предположим, например, что вы хотите -1 , когда ни один элемент не удовлетворяет условию ! = X ,

return next((i for i, v in enumerate(L) if v != x), -1)

Это синтаксис Python 2.6; если вы застряли с 2.5 или более ранней версией, .next () является методом genexp (или другого итератора) и не принимает значение по умолчанию, такое как -1 выше (поэтому, если вы не хотите видеть исключение StopIteration , вам придется использовать try / , кроме ). Но есть причина, по которой после 2.5 было выпущено больше выпусков - постоянное улучшение языка и его встроенных модулей! -)

17
ответ дан 30 November 2019 в 21:28
поделиться

Глупое решение на основе itertools :)

import itertools as it, operator as op, functools as ft

def index_ne(item, sequence):
    sequence= iter(sequence)
    counter= it.count(-1) # start counting at -1
    pairs= it.izip(sequence, counter) # pair them
    get_1st= it.imap(op.itemgetter(0), pairs) # drop the used counter value
    ne_scanner= it.ifilter(ft.partial(op.ne, item), get_1st) # get only not-equals
    try:
        ne_scanner.next() # this should be the first not equal
    except StopIteration:
        return None # or raise some exception, all items equal to item
    else:
        return counter.next() # should be the index of the not-equal item

if __name__ == "__main__":
    import random

    test_data= [0]*20
    print "failure", index_ne(0, test_data)

    index= random.randrange(len(test_data))
    test_data[index]= 1
    print "success:", index_ne(0, test_data), "should be", index

Все это просто для того, чтобы воспользоваться преимуществом itertools.count подсчета :)

{{1 }}
-1
ответ дан 30 November 2019 в 21:28
поделиться

enumerate () возвращает итератор, который возвращает кортеж текущего индекса итерируемого объекта, а также самого элемента.

4
ответ дан 30 November 2019 в 21:28
поделиться
[i for i, x in enumerate(my_list) if x != value][0]

Если вы не уверены, есть ли несоответствующий элемент, используйте вместо этого следующее:

match = [i for i, x in enumerate(my_list) if x != value]
if match:
    i = match[0]
    # i is your number.

Вы можете сделать его еще более «функциональным» с помощью itertools , но вы скоро достигнете точки, где лучше использовать простой цикл for. Даже приведенные выше решения не так эффективны, как цикл for, поскольку они создают список всех несовпадающих индексов, прежде чем вы выберете интересующий.

1
ответ дан 30 November 2019 в 21:28
поделиться

Использование понимания списка, когда вам нужно только первое, просто кажется неприятным (для меня). Используйте цикл for и выходите раньше.

>>> lst = [None, None, None, "foo", None]
>>> for i, item in enumerate(lst):
...   if item: break
... else:
...   print "not found"
... 
>>> i
3
5
ответ дан 30 November 2019 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: