2015-05-25 43 views
6

Czy istnieje opcja filtrowania tych ciągów z listy ciągów zawierających na przykład 3 równe znaki z rzędu? Stworzyłem metodę, która może to zrobić, ale jestem ciekawy, czy jest tam bardziej pytonowo lub bardziej wydajnie lub prostszy sposób na zrobienie tego.Filtruj ciągi znaków, gdy n ma równe znaki z rzędu

list_of_strings = [] 


def check_3_in_row(string): 
    for ch in set(string): 
     if ch*3 in string: 
      return True 
    return False 

new_list = [x for x in list_of_strings if check_3_in_row(x)] 

EDIT: Właśnie dowiedziałem się jedno rozwiązanie:

new_list = [x for x in set(keywords) if any(ch*3 in x for ch in x)] 

Ale nie jestem pewien, w jaki sposób jest szybszy - regexp lub to.

+0

Powiązane: [użyj ponownie, aby znaleźć kolejno powtarzające się znaki] (http://stackoverflow.com/questions/7147796/python-use-re-to-find-consecutively-repeated-chars) –

Odpowiedz

6

Można użyć wyrażeń regularnych, jak to

>>> list_of_strings = ["aaa", "dasdas", "aaafff", "afff", "abbbc"] 
>>> [x for x in list_of_strings if re.search(r'(.)\1{2}', x)] 
['aaa', 'aaafff', 'afff', 'abbbc'] 

Tutaj, . dopasowuje dowolny znak i jest ujęte w jednej grupie ((.)). I sprawdzamy, czy ten sam przechwycony znak (używamy odwołania wstecznego \1 odnoszą się do pierwszej przechwyconej grupy w ciągu znaków) pojawia się jeszcze dwa razy ({2} oznacza dwa razy).

+0

Dzięki za odpowiedź. Ładne rozwiązanie. Dowiedziałem się już w jeden sposób - zredagowałem mój post. –

+0

@Milan Do sprawdzenia możesz użyć modułu 'timeit'. Jednak wersja RegEx może być lepsza niż twoja wersja "any". – thefourtheye

+0

Moje _guess_ jest takie, że wyrażenie regularne będzie szybsze, jeśli ciągi są długie, ponieważ skanuje tylko każdy ciąg jeden raz, podczas gdy metoda 'any()' skanuje ciąg znaków _n_ __ razy. OTOH, jeśli większość ciągów na liście _do_ zawiera grupę 3, a ta grupa ma tendencję do występowania w pobliżu początku łańcucha, wtedy 'dowolne()' podejście _może_ będzie szybsze. –