Wymienić zrozumienia i warunki?

Próbuję sprawdzić, czy mogę ulepszyć ten kod, używając list składanych.
Powiedzmy, że mam następujące listy:

a_list = [
        'HELLO',
        'FOO',
        'FO1BAR',
        'ROOBAR',
        'SHOEBAR'
        ]

regex_list =   [lambda x: re.search(r'FOO', x, re.IGNORECASE),
                lambda x: re.search(r'RO', x, re.IGNORECASE)]

Zasadniczo chcę dodać wszystkie elementy, które nie mają żadnych dopasowań w regex_list do innej listy.

E.g. ==>

newlist = []
for each in a_list:
    for regex in regex_list:
        if(regex(each) == None):
            newlist.append(each)

Jak mogę to zrobić za pomocą list składanych? Czy to w ogóle możliwe?


person UberJumper    schedule 05.05.2009    source źródło
comment
-1: lambdy. Po prostu użyj samego wyrażenia regularnego, nie trać czasu na zawijanie idealnie dobrego wyrażenia regularnego w funkcję.   -  person S.Lott    schedule 05.05.2009


Odpowiedzi (2)


Jasne, myślę, że to powinno wystarczyć

newlist = [s for s in a_list if not any(r(s) for r in regex_list)]

EDYTUJ: przy bliższym przyjrzeniu się zauważyłem, że twój przykładowy kod faktycznie dodaje do nowej listy każdy ciąg w a_list, który nie pasuje do wszystkich wyrażeń regularnych – i co więcej, dodaje każdy ciąg tylko raz dla każdego wyrażenia regularnego, które nie pasuje. Moje rozumienie listy robi to, o czym myślę, że miałeś na myśli, czyli dodawanie tylko jednej kopii każdego ciągu, który nie pasuje do żadnego wyrażenia regularnego.

person David Z    schedule 05.05.2009
comment
Nie to samo zachowanie, co kod, który podał, ponieważ każdy z nich nigdy nie zostanie dodany więcej niż raz, jak w przykładzie. Uważam jednak, że właśnie to chciał osiągnąć. - person bayer; 05.05.2009
comment
Jeszcze jedno pytanie, gdybym miał zamienić a_list na funkcję zwracającą listę. Czy zostanie wywołany tylko raz? Czy będzie wywoływany przy każdej iteracji? np. def returnalist(): return ['klsdfj', 'kldffjsdkl', 'hello', 'cośhats'] i zrobił: newlist = [s for s in returnalist(), jeśli nie any(r(s) for r in regex_list)] Czy osoba powracająca byłaby stale wzywana? - person UberJumper; 05.05.2009
comment
W tym przypadku należy go wywołać tylko raz. Chociaż zawsze można było spróbować i zobaczyć ;-) - person David Z; 06.05.2009
comment
David, dziękuję Ci za pokazanie mi jakiegokolwiek potencjału. Nie używałem go wcześniej. - person praavDa; 06.05.2009

Skróciłbym twój kod do tego:

a_list = [
          'HELLO',
          'FOO',
          'FO1BAR',
          'ROOBAR',
          'SHOEBAR'
          ]
regex_func = lambda x: not re.search(r'(FOO|RO)', x, re.IGNORECASE)    

Wtedy masz dwie opcje:

  1. Filtr

    newlist = filter(regex_func, a_list)

  2. Lista zrozumienia

    newlist = [x for x in a_list if regex_func(x)]

person johannix    schedule 05.05.2009