Предположим, у нас есть строки типа:
test= '--a-kbb-:xx---xtx:-----x--:---g-x--:-----x--:------X-:XXn-tt-X:l--f--O-'
то есть они всегда состоят из 8 разделов, разделенных знаком :
, поэтому можно разбить строку на список, в котором каждый элемент соответствует разделу:
testsep = test.split(':')
давать
['--a-kbb-', 'xx---xtx', '-----x--', '---g-x--', '-----x--', '------X-', 'XXn-tt-X', 'l--f--O-']
Теперь я хочу проверить, является ли строка test
такой, что в 3 последовательных разделах x
встречается в одной и той же позиции раздела. Например, с приведенным выше test
мы находим хотя бы один такой случай: считая от 1, разделы 2,3 и 4 содержат x
в той же позиции, а именно в индексе 6. Следовательно, наша тестовая строка здесь соответствует искомому шаблону. .
Наивный подход состоял бы в том, чтобы разбить, затем перебрать все разделы и посмотреть, есть ли последовательные разделы, имеющие x
в каждой возможной позиции (первый индекс 1, 2, ... до 8), но это было бы не очень питон- подобно.
Вы можете превратить свою строку в матрицу с 1 вместо «x» и 0 в другом месте; затем суммируйте по столбцу и проверьте, равна ли какая-либо сумма или больше 3
@ Дон, а, так аккуратно, спасибо! Не стесняйтесь также добавить это в качестве ответа для будущих читателей.
Спасибо. Посмотрите мой ответ для альтернативного решения
Можно использовать itertools.groupby
с class
для группировки последовательностей строк, которые все имеют x
в одной и той же позиции:
from itertools import groupby
class X:
def __init__(self, _x):
self.x = _x
def __eq__(self, _val):
return any(a == 'x' and b =='x' for a, b in zip(self.x, _val.x))
d = ['--a-kbb-', 'xx---xtx', '-----x--', '---g-x--', '-----x--', '------X-', 'XXn-tt-X', 'l--f--O-']
result = [[a, [i.x for i in b]] for a, b in groupby(list(map(X, d)))]
final_result = [b for _, b in result if any(all(h == 'x' for h in c) for c in zip(*b))]
Выход:
[['xx---xtx', '-----x--', '---g-x--', '-----x--']]
Однако гораздо проще использовать наивный подход, и действительно, решение довольно питоническое:
def group(d):
start = [d[0]]
for i in d[1:]:
if any(all('x' == c for c in b) for b in zip(*(start+[i]))):
start.append(i)
else:
if len(start) > 1:
yield start
start = [i]
print(list(group(d)))
Выход:
[['xx---xtx', '-----x--', '---g-x--', '-----x--']]
Привет, Аякс, надеюсь, ты в порядке. Мне было интересно, если позволяет время, не могли бы вы взглянуть на этот недавний пост (несколько связанный): stackoverflow.com/q/64106974/7685268 любой отзыв будет полезен. Спасибо в любом случае
Это достаточно по-питоновски?
str = '--a-kbb-:xx---xtx:-----x--:---g-x--:-----x--:------X-:XXn-tt-X:l--f--O-'
sections = str.split (':')
reduce (lambda a, b: a | ('xxx' in b), [reduce(lambda c, d: c + d, map(lambda c: c[i], sections), '') for i in range(reduce (lambda e, f: max (e, len (f)), sections, 0))], False)
Объяснение
reduce (lambda e, f: max (e, len (f)), sections, 0)
вычисляет максимальную длину участка;
for i in range(reduce (lambda e, f: max (e, len (f)), sections, 0))
повторяет i
от нуля до максимальной длины секции минус 1;
map(lambda c: c[i], sections)
вычисляет список i-х символов всех секций;
reduce(lambda c, d: c + d, map(lambda c: c[i], sections), '')
вычисляет строку, состоящую из i-х символов всех секций;
[reduce(lambda c, d: c + d, map(lambda c: c[i], sections), '') for i in range(reduce (lambda e, f: max (e, len (f)), sections, 0))]
вычисляет список строк, где i-я строка состоит из i-х символов всех разделов;
и окончательное выражение возвращает True
в случае, если любая из строк в списке, рассчитанном на предыдущем шаге, содержит три последовательных 'x'.
Выберите каждый 9-й элемент и проверьте, есть ли 3 последовательных 'x':
test= '--a-kbb-:xx---xtx:-----x--:---g-x--:-----x--:------X-:XXn-tt-X:l--f--O-'
for i in range(9):
if 'xxx' in test[i::9]:
print("Pattern matched at position %d" % i)
break
else:
print("Pattern not matched")
дает
Pattern matched at position 5
Укороченная версия:
>>> any(('xxx' in test[i::9] for i in range(9)))
True
Вы думали об использовании регулярных выражений? Шаблон уже известен или вам нужно определить шаблон?