Найти все совпадения в списке - PullRequest
0 голосов
/ 11 сентября 2018

Я пытаюсь перечислить все совпадения элемента в списке.Но ошибаюсь.что не так в приведенном ниже коде.

theList = ['a','e','i','o','u','e','o','e']

def matchall1(theList, value, pos=0):
    loc = pos - 1
    try:
        loc = theList.index(value, loc+1)
        yield loc
    except ValueError:
        pass

value = 'e'
for loc in matchall1(theList, value):
    print("match at", loc+1, "position.")

Результат, который я получаю из вышеприведенного кода, это всего лишь ¨match на 2 позиции. ¨

Ответы [ 6 ]

0 голосов
/ 11 сентября 2018

Если вы хотите найти все совпадения, вам потребуется некоторая форма повторения (итеративный цикл или рекурсия).

Судя по сигнатуре вашей функции, которую вы намеревались использоватьрекурсия, которая будет выглядеть следующим образом:

def matchall_version1(theList, value, i=0):
    try:
        i = theList.index(value, i)
        yield i
        yield from matchall_version1(theList, value, i+1)
    except ValueError:
        pass

И используя цикл, ваш код будет выглядеть так:

def matchall_version2(theList, value):
    i = 0
    try:
        while True:
            i = theList.index(value, i + 1)
            yield i
    except ValueError:
        pass

Однако я хотел бы предложить эту другую версию, которая гораздо болеечитаемее, чем у вас imho:

def matchall_version3(theList, value):
    for i, x in enumerate(theList):
        if x == value:
            yield i

Все три версии дают одинаковый результат.This:

theList = ['a','e','i','o','u','e','o','e']
print(list(matchall_version1(theList, 'e')))
print(list(matchall_version2(theList, 'e')))
print(list(matchall_version3(theList, 'e')))

Печатает это:

[1, 5, 7]
[1, 5, 7]
[1, 5, 7]
0 голосов
/ 11 сентября 2018
theList = ['a','e','i','o','u','e','o','e']

def matchall1(theList, value, pos=0):
    loc = pos - 1
    loc = [i for i, v in enumerate(theList) if v == value]
    for p in loc:
        yield p

value = 'e'
for loc in matchall1(theList, value):
    print("match at", loc+1, "position.")
0 голосов
/ 11 сентября 2018

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

theList = ['a','e','i','o','u','e','o','e']

def matchall1(theList, value, pos=0):
    loc = pos - 1
    try:
        for items in theList:  #ADD THIS TO YOUR CODE AND YOU'LL BE GOOD
            loc = theList.index(value, loc+1)
            yield loc
    except ValueError:
        pass

value = 'e'
for loc in matchall1(theList, value):
    print("match at", loc+1, "position.")

Это даст вам исчерпывающий результат.т.е. по одному за раз.Если вам нужны все позиции в одном и том же операторе вывода, я бы предложил добавить его в список, а затем передать его в цикл for, реализованный позже.

РЕДАКТИРОВАТЬ 1: IВы быстро добавили часть, где вы можете вывести все позиции в одном выраженииКод может выглядеть неприятно, и не-Professional , но это работает.Взгляните на это

theList = ['a','e','i','o','u','e','o','e']

def matchall1(theList, value, pos=0):
    loc_list = []
    loc = pos - 1
    try:
        for items in theList:
            loc = theList.index(value, loc+1)
            loc_list.append(loc)
            yield loc_list
    except ValueError:
        pass

value = 'e'
for loc in matchall1(theList, value):
    continue
new_loc = []
for x in loc:
    x+=1
    new_loc.append(x)

pos = ",".join(str(x) for x in new_loc)

print("Match at", pos, "position.")

Вывод:

Match at 2,6,8 position.
0 голосов
/ 11 сентября 2018

Это может быть так просто, как вы забыли цикл :

def matchall1(theList, value, pos=0):
    loc = pos - 1
    try:
        while True:  # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            loc = theList.index(value, loc+1)
            yield loc
    except ValueError:
        pass

value = 'e'
for loc in matchall1(theList, value):
    print("match at", loc+1, "position.")

Выход:

match at 2 position.
match at 6 position.
match at 8 position.
0 голосов
/ 11 сентября 2018

Алгоритм немного запутанный, лучше использовать выражение генератора:

theList = ['a','e','i','o','u','e','o','e']
def matchAll(element, lst):
    yield from (i for i, e in enumerate(lst) if e == element)

Здесь у вас есть живой пример

0 голосов
/ 11 сентября 2018

Вы можете сделать это путем понимания списка

[index for index, letter in enumerate(theList) if letter==value]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...