2016-12-13 2 views
0

더 나은 방법이 있는지 궁금합니다.re.findall()에서 작동

aList = regexObj.findall(s.text) if regexObj.findall(s.text) else None 

self._menuUrls = map(lambda x: str('https://....' + x + '?otherparams=...'), aList) 

나는이 작업을 수행하는 데 사용할 수있는 미리 만들어진 방법이 있나요 : 나는 전체 목록을 발견 한 다음 목록의 각 항목을 변환 대를 발견하면 나는 문자열로 발견 된 각 개체를 변환하고 싶습니다 하나의 패스에서 또는 내가 별도의 메소드/lambda를 만들 것을 요구할 것인가? 내가 어떻게 접근하는 것이 더 효율적일까요?

EDIT : 500k 일치 인스턴스가 포함 된 파일로 여러 가지 방법을 연구했습니다. re.findall()을 사용한 목록 이해가 re.finditer()를 사용하여 목록 이해보다 40-50 % 빠릅니다. 항목을 검색 할 때 개체입니다.

menuUrls = [] 

start = time.time() 

regex = re.compile("javascript:iframeLink\('([^']+)'\);") 

#My Original Solution = 0.78200006485 
menuUrls = map(lambda x: str('http://...' + x + '?param=...'), regex.findall(str(lines))) 

#My Revised Solution = 0.619000196457 
menuUrls = [ str('http://...' + x + '?param=...') for x in regex.findall(str(lines)) ] 

#Friend's Proposal = 0.802000045776 
for m in regex.finditer(str(lines)): 
    menuUrls.append(str('http://...' + m.group(1) + '?param=...')) 

#Stack Proposal = 0.912000179291 
menuUrls = [ str('http://...' + x.group(0) + '?param=...') for x in regex.finditer(str(lines)) ] 

set(menuUrls) 

print time.time() - start 
+0

음, 우선,'aList = regexObj.findall (s.text) else None'은'regexObj.findall (s.text)'를 두 번 호출하기 때문에 매우 비효율적입니다 ... –

답변

0
menuUrls = [] 

start = time.time() 

regex = re.compile("javascript:iframeLink\('([^']+)'\);") 

#My Original Solution = 0.78200006485 
menuUrls = map(lambda x: str('http://...' + x + '?param=...'), regex.findall(str(lines))) 

#My Revised Solution = 0.619000196457 
menuUrls = [ str('http://...' + x + '?param=...') for x in regex.findall(str(lines)) ] 

#Friend's Proposal = 0.802000045776 
for m in regex.finditer(str(lines)): 
    menuUrls.append(str('http://...' + m.group(1) + '?param=...')) 

#Stack Proposal = 0.912000179291 
menuUrls = [ str('http://...' + x.group(0) + '?param=...') for x in regex.finditer(str(lines)) ] 

set(menuUrls) 

print time.time() - start 

regex.findall의 지능형리스트는() 테스트가 가장 빠른 검색하고 제안 된 솔루션의 기능을 변환

0

당신은 re.finditer 찾고 있습니다. 뭔가 같이 :

regex_iter = regexObj.finditer(s.text) 
self._menuUrls = ['https://....' + x.group(0) + '?otherparams=...' for x in regex_iter] 

이 한계이지만, 일반적으로 지능형리스트 (다른 ​​비 내장 함수와 map보다, 실제로)를 lambdamap보다 빠르게 될 것입니다.

데모 :

>>> import re 
>>> text = "1 234 6 889 33 5 777 dff hd ae 2 ggre 777 fdf" 
>>> pattern = re.compile(r"\d+") 
>>> nums = ['<'+ m.group(0) + '>' for m in pattern.finditer(text)] 
>>> nums 
['<1>', '<234>', '<6>', '<889>', '<33>', '<5>', '<777>', '<2>', '<777>'] 
>>>