2013-02-08 2 views
1

나는 파이썬으로 코드를 작성하고 있는데, 단어 목록이 긴 문자열인지 확인하고 싶다. 나는 그것을 여러 번 반복 할 수 있다는 것을 알고 있으며, 그것은 똑같은 일일 수 있습니다. 그러나 그것을 수행하는 더 빠른 방법이 있는지 TP가보고 싶었습니다.목록과 문자열에서 일치하는 단어 찾기

keyword_list = ['motorcycle', 'bike', 'cycle', 'dirtbike'] 
if item in keyword_list in all_text: 
      print 'found one of em' 

효율적으로이 작업을 수행 어쨌든 거기 :

all_text = 'some rather long string' 
    if "motorcycle" in all_text or 'bike' in all_text or 'cycle' in all_text or 'dirtbike' in all_text: 
     print 'found one of em' 

하지만 내가하고 싶은 것은 이것이다 : 내가 현재하고있는 중이 야하는 것은 이것이다? 내가 할 수있는 걸 깨닫습니다 :

keyword_list = ['motorcycle', 'bike', 'cycle', 'dirtbike'] 
for item in keyword_list: 
     if item in all_text: 
      print 'found one of em' 

키워드 목록이 길어지면 더 좋은 방법이 될 것 같습니다.

답변

11

당신은 여전히 ​​텍스트로 발견 적어도 하나까지 모두 확인해야하지만, 더 간결 수 있습니다

keyword_list = ['motorcycle', 'bike', 'cycle', 'dirtbike'] 

if any(word in all_text for word in keyword_list): 
    print 'found one of em' 
+1

'keyword_list'를'set'으로 만들 수 있습니다 –

+0

다른 방법으로 확인하는 것이 더 효율적입니다 :'any (단어 안에있는 단어의 단어)' – georg

+0

텍스트는 단어 목록이 아니며, 먼저 분할해야합니다. –

4

한 가지 방법은 키워드 목록 밖으로 prefix tree을 구축하는 것입니다 . 그런 다음 문자 당 긴 문자열 문자를 반복 할 수 있습니다. 각 반복에서 접두어 트리에서 현재 위치에서 시작하는 큰 문자열의 접두사를 찾으려고합니다. 이 작업은 시간이 O(log k) 시간이 걸리며 키워드 목록의 크기는 k입니다 (접두사 트리가 균형 상태라고 가정). 긴 문자열의 길이가 n 인 경우 전체 복잡성은 O(n log k)이며 k가 큰 경우 순한 O(n k)보다 훨씬 좋습니다.

4

어때?

>>> keyword_list = ['motorcycle', 'bike', 'cycle', 'dirtbike', "long"] 
>>> all_text = 'some rather long string' 
>>> if set(keyword_list).intersection(all_text.split()): 
...  print "Found One" 
Found One 
+0

'set' 사용에 대한 좋은 아이디어. 그러나, 사실 값을 찾기 위해 전체 lot을 교차시킬 필요가 없습니다 ... 대신에'keyword_list' 세트에 대해'any'와 generator를 사용하십시오 ... 또한, 당신의 예제에서'set (keyword_list). intersection (all_text.split())'- 불필요한 변환을 피할 수 있습니다. –

+0

@Jon 정보 주셔서 감사합니다. – Rakesh

1

는 나중에 변수를 all_text해야하거나 늘 정규 표현식은 아마 빠른 방법입니다 사용

keyword_list = ['motorcycle', 'bike', 'cycle', 'dirtbike'] 
all_text = input("what kind of bike do you like?") 
for item in keyword_list: 
     if item in all_text: 
      print ('found one of em') 
0

작동합니다.

re.findall(r'motorcycle|bike|cycle|dirtbike', text) 

은 선택한 단어의 모든 일치 항목을 반환합니다.

+0

이것은 잘못된 아이디어입니다. 예를 들어,'| cycle |'은 자전거, 세발 자전거, 외바퀴 자전거 등과 일치 할 것이기 때문에 명확히 원래 저자의 의도는 아닙니다. 이 정규 표현식을 개선하여 단어 경계 표기법 등을 사용할 수는 있지만 읽을 수 없게 만들 수 있습니다. 원저자는 "효율적인"(가장 빠른 실행 시간 - 최소의 메모리 사용?) 코드를 정의하는 방법을 지정하지 않았지만 정규 표현식은 CPU와 RAM에서 매우 비효율적입니다. *이 특별한 * 정규식은 아니지만 일반적인 솔루션 클래스로서주의를 기울여 제안해야합니다. –

관련 문제