поиск списка кортежей с подстановочными знаками? - PullRequest
1 голос
/ 30 декабря 2010

как мне найти список кортежей, если я знаю только 1 элемент любого кортежа в списке?

пример макета (это не работает):

tuplelist = [('cat', 'dog'), ('hello', 'goodbye'), ('pretty', 'ugly')]
matchlist = []
searchstring = 'goodbye'

if (*, searchstring) in tuplelist:
    print "match was found"
    matchlist.append(tuplelist[#index of match])

theв asterix я хочу поставить подстановочный знак

Я знаю, что мог бы использовать:

for i in range (len(tuplelist)):
    if tuplelist[i][1]==searchstring:
        matchlist.append(tuplelist[i])
        print "match was found"

, но проблема в том, что мне нужно запускать определенную функцию только один раз, если совпадение не найдено.

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

    if i==len(tuplelist) and matchcounter==0:
        #do something
        print "no match was found"

Но я думаю, что это уродливо и запутанноя уверен, что есть более чистый способ сделать это: P

Ответы [ 6 ]

6 голосов
/ 22 октября 2013

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

Есть вариант для...else конструировать в Python только для этого варианта использования.Вы можете сделать это (я собираюсь использовать код Марка Байерса и изменить его):

for t in tuplelist:
    if t[1] == searchstring:
        #do something
        print "match was found"
        break
else:
    print "not matches found"
    # call function if not matches were found.

Секция else происходит только в том случае, если цикл завершается нормально (без разрывов).

4 голосов
/ 30 декабря 2010

Вы можете сделать это:

found_match = False

for t in tuplelist:
    if t[1] == searchstring:
        #do something
        print "match was found"
        found_match = True

if not found_match:
    # ...
3 голосов
/ 30 декабря 2010

I думаю вы пытаетесь выполнить частичное упорядоченное сопоставление;следующее использует None в качестве подстановочного знака:

def tupleMatch(a,b):
    return len(a)==len(b) and all(i is None or j is None or i==j for i,j in zip(a,b))

def tupleCombine(a,b):
    return tuple([i is None and j or i for i,j in zip(a,b)])

def tupleSearch(findme, haystack):
    return [tupleCombine(findme,h) for h in haystack if tupleMatch(findme, h)]

findme = (None, "goodbye")
haystack = [
    ('cat', 'dog'),
    ('hello', 'goodbye'),
    ('pretty', 'ugly'),
    ('tomorrow', 'goodbye'),
    ('goodbye', 'today'),
    ('anything', None)
]
tupleSearch(findme, haystack)

возвращает

[('hello', 'goodbye'), ('tomorrow', 'goodbye'), ('anything', 'goodbye')]
3 голосов
/ 30 декабря 2010

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

tuplelist = [('cat', 'dog'), ('hello', 'goodbye'), ('pretty', 'ugly')]
if 'goodbye' in (x[1] for x in tuplelist):
    print "match was found"

Это берет список кортежей и строит список (фактически выражение генератора), содержащий только вторые элементы из каждого кортежа; затем он проверяет строку поиска на членство в этом новом списке.

1 голос
/ 30 декабря 2010
pairs = [('cat', 'dog'), ('hello', 'goodbye'), ('pretty', 'ugly')]
matches = [p for p in pairs if p[1] == 'goodbye']

Готово. Нет суеты, нет суеты. Вы слишком стараетесь делать вещи так, как вы делаете это на императивных языках. Перестаньте пытаться рассказать Python, как это сделать, и скажите, что делать.

но проблема в том, что мне нужно запускать определенную функцию только один раз, если совпадений не найдено.

... Итак, проверьте список позже: если он пустой, то совпадений не найдено. В чем проблема?

1 голос
/ 30 декабря 2010
def f(x,y): return 'did something with (%s,%s)' % (str(x), str(y))

matches = [f(a,b) for a,b in tuplelist if b == searchstring]
if not matches:
    #do something else
    pass
...