2014-04-27 3 views
0

각 튜플이 (val1, val2) 인 500,000 개의 항목이 있습니다. 특정 조건의 요소를 통해 루프 빠른 방법이 있다면, 궁금하지만조건 루프가있는 루프 제한

if val2 == someval: 
    do_something() 
    break 

: 같은

현재, 나는 목록을 루프 내에서 반복하고, 나는 조건이 , 같은 항목을 통해 반복에만 val2 == someval보다는 전체 목록을 수표를하고 목록.

+1

목록을 'val2' (으)로 정렬하지 않는 한. – Blorgbeard

+0

@ Pat841 : 질문하신 질문의 대부분은 대답이 부족합니다. –

답변

0

빠른 방법이 확실하지 않습니다. 내가보기에는 먼저 목록에서 "val2"를 찾아야합니다. 내 경험상 루프가 필요합니다.

-1

두 가지 질문을하는 것 같습니다. 첫 번째로 당신이 뭔가를 볼 수있는 것은 당신이 깨뜨린 것, 다른 하나는 someval과 동등한 것을 보는 것입니다. 후자의 경우, 즉 :

"그러나 특정 상황에서 요소를 반복하는 빠른 방법이 있었는지 궁금합니다. 예를 들어 전체 목록이 아닌 val2 == someval 인 항목을 반복하는 경우 수표. "

당신은 할 수 있습니다 :

for i in filter(lambda t: t[1] == someval, val_list): 
    stuff 

또는 지능형리스트를 통해 :

for i in [x for x in val_list if x[1] == someval]: 
    stuff 

내 생각 엔 이들 중 하나가 빠른 것입니다.

+0

당신의 추측은 잘못되었습니다. 이러한 임의의 주장을하기 전에 항상 벤치마킹하십시오. IPython은 2 개 이상의 코드 스 니펫을 비교하는 데 사용할 수있는 편리한'timeit' 명령을 가지고 있습니다. –

-1

언제든지 val2 == someval에있는 모든 요소를 ​​확인하고 목록이 튜플의 두 번째 값으로 정렬되지 않았는지 확인해야하므로 모든 요소를 ​​반복 할 수 없습니다 피하십시오.

그러나 목록을 반복하는 데 사용하는 방법이 가능한 한 효율적인지 확인할 수 있습니다. 예를 들어, for statement을 사용하는 대신 list comprehensions을 사용하면 val2 == someval을 만족하는 값을 필터링하고 반환되는 목록이 비어 있지 않은 경우 do something을 필터링 할 수 있습니다. 나는 "may"이라고 말합니다. 왜냐하면 그것은 실제로 여러분의 데이터의 배포에 의존하기 때문에; 당신이 val2 == someval이 사실이 보유하고있는 모든 값을 가지고 어떤 행동 등

파이썬 3.x를 다음 "list comprehensions and generator expressions in Python 3 are actually faster than they were in Python 2"을 사용하는 경우를 수행하기에 그것은 유용 여부.

+0

리스트 comprehensions은 이것을 더 빠르게 만들지 않을 것입니다; 사실 그들은 목록의 모든 항목을 거쳐 다른 목록을 작성하기 때문에 훨씬 더 나쁠 것입니다. 생성기 표현식은 'for' 루프보다 빠르지 만 괜찮지는 않을 것입니다. –

+0

목록 내포물이 약간 더 빠릅니다. 새로운 목록을 만들고 초기 목록 전체를 반복해야하지만 사실상 "for 문"을 능가하지는 않을 것입니다. – s16h

+0

루프 중에 새로운 목록을 생성 할 필요가 없다면 'for' 루프보다 성능이 뛰어날 수는 없습니다. 그래도 벤치 마크 예제를 통해 나를 설득 시키십시오. –

1

어떤 다른 측면에서 그것을 복용에 대한 :

if someval in lst: 
    my_action(somewal) 

LST에서 somewal 회원의 테스트는 루프를 필요로하지만, 더 빨리 될 수 있도록이, C에 더 최적화 된 코드에서 실행됩니다.

다음
In [49]: x = 3 

In [50]: %timeit x in [1, 2, 3] 
10000000 loops, best of 3: 53.8 ns per loop 

In [51]: %timeit x == 1 or x == 2 or x == 3 
10000000 loops, best of 3: 85.5 ns per loop 

In [52]: x = 1 

In [53]: %timeit x in [1, 2, 3] 
10000000 loops, best of 3: 38.5 ns per loop 

In [54]: %timeit x == 1 or x == 2 or x == 3 
10000000 loops, best of 3: 38.4 ns per loop 

당신이 볼 수있는, 테스트에 "곧"입니다 숫자에 대한 즉, 시간 차이는 무시할이지만은 "나중에"이 회원 자격을 테스트하는 빠릅니다.

보다 현실적인 측정의 경우 : 중앙의 번호의 존재를 테스트하고, 500,000 번호 범위를 갖는

In [64] lst = range(500000) 

In [65]: %%timeit 
250000 in lst 
    ....: 
100 loops, best of 3: 2.66 ms per loop 

In [66]: %%timeit 
for i in lst: 
    if i == 250000: 
    break 
    ....: 
100 loops, best of 3: 6.6 ms per loop 

필요한 시간 다운 멤버십 시험 40 %까지 떨어진다 x in lst

+0

'[1, 2, 3]의 x가'x == 1 또는 x == 2 또는 x == 3 '보다 빠릅니까? –

+1

@ErikAllik 예, 있습니다. 내 업데이트 답변을 참조하십시오. –

+0

좋아, 그 작은 세트를 위해 일조차 몰랐다; 나는 PyPy에서, 그것은 다른 이야기라고 생각한다. –

-1
  1. 루프 또는 if을 피할 방법이 없습니다. 더 빠른 방법이 있다는 제안은 잘못된 것입니다. filter 및 목록 내재는 이 아니며은 문제를 한 번 개선합니다. 사실, 게으른 평가를받는 생성자 표현을 사용하지 않으면 이해 (filter은 물론)로 인해 (잠재적으로 훨씬) 느리고 메모리가 많이 소비됩니다. 그리고 생성자 표현은 성능을 향상시키지 못합니다.

  2. C 또는 Java와 같은 언어로 다시 작성하거나 PyPy 또는 Cython을 사용하는 것 이외에는 더 빨리 만들 수있는 방법이 없습니다. for x in ...: if x ...: do_smth()은 이미 가장 빠른 방법입니다. 물론 데이터에 따라 실제로 정렬 된 방식으로 데이터 구조 (500 000 개의 항목이 있음)를 작성할 수 있으므로 목록의 시작 부분 만 반복 할 수 있습니다. 또는 특정 조건을 만족하는 항목을 별도의 목록/집합/썸네일로 수집하면 나중에 필터링 및 전체 루프 반복을 완전히 피함으로써 매우 좋은 결과를 얻을 수 있습니다.

+0

Downvoter : 정교하게 신경 쓰시겠습니까? –

0

예를 들어이 코드는 루프를 반복하고 경우에만 val2만큼 == someval VAL1 인쇄됩니다.

for val1, val2 in some_list: 
    if val2 != someval: 
     continue 
    print val1