我有以下列表:someList = ['blablahihix', 'somethinghihi']
我希望返回一个列表,其中包含列表中两个元素之间的重复模式(在本例中为' hihi')。
这就是我正在做的事情:
p, r = re.compile(r'(.+?)\1+'), []
for i in strList:
r.extend(p.findall(i) or [i])
当我print r
时,它会给我['bla', 'hi', 'hi']
。我唯一想要的是['hihi']
。我不想要' blabla'要归还,因为我没有' blabla'在列表的第二个元素中。
我错过了什么?
答案 0 :(得分:1)
使用set
操作获取匹配组的交集:
>>> strList = ['blablahihix', 'somethinghihi']
>>> p = re.compile(r'(.+?)\1+')
>>> [set(p.findall(i)) for i in strList]
[{'bla', 'hi'}, {'hi'}]
>>> # from functools import reduce # In Python 3.x
>>> reduce(lambda a, b: a & b, (set(p.findall(i)) for i in strList))
{'hi'}
使用set & set
or set.intersection
来获得两个匹配中出现的共同部分。
您需要修改模式或使用re.finditer
,因为re.findall
根据是否使用捕获组返回的方式;如果模式中存在一个或多个组,则返回组列表而不是整个匹配字符串列表。
>>> import re
>>>
>>> strList = ['blablahihix', 'somethinghihi']
>>> p = re.compile(r'(.+?)\1+')
>>> reduce(lambda a, b: a & b,
(set(m.group() for m in p.finditer(i)) for i in strList))
{'hihi'}
<强>更新强>
正如georg建议的那样,你可以使用set.intersection(*...)
;不需要使用reduce
。
>>> set.intersection(*(set(m.group() for m in p.finditer(i)) for i in strList))
{'hihi'}