2016-08-10 2 views
0

에서 테스트를 실행하지 않고 테스트를 통과 반복기의 처음 n 항목을 반환하는 xxx는 비쌉니다.어떻게 내가 좋아하는 뭔가를 찾고 있어요 나머지

나는

def blah (list, len): 
    res=[]; i=0; 
    while i<len: 
     if xxx(list[i]): 
      res.append(i) 
    return res 

과 같은 하위 기능을 쓸 수 있지만, 이것은 매우 unpythonic 보인다.

첫 번째 결과를 증명하는 예는 잘못된 일이 될 것이다 수행합니다

foo = [ p for p in (1,2,3,4,5,0,6) if 100/p ][0:3] 

는 [1,2,3]을 반환하지만, 실제로 0으로 나누기에 실패 "해야한다".

itertools에서 다양한 도구를 사용해 보았지만 크기에 도달 한 후 반복자의 실행을 중지시키는 조합을 찾을 수 없습니다. 이 지능형리스트와 함께 할 불가능한 generator comprehension

답변

2

itertools.islice을보십시오.

둘 사이의 차이점은 무엇입니까? List comprehensions은 iterable에 대한 작업을 한 번에 반복하고 목록을 사용자에게 반환합니다. 여기에있는 열쇠는 이며 모두 한 번에입니다.

귀하의 예는 목록 내포물을 사용하며 다음과 같은 현상이 발생합니다. 우선 목록 이해력이 평가됩니다. 귀하의 경우에는 실패하지만, 실패하지 않았더라도 iterable somelist의 모든 내용을 반복하여 결과 목록을 반환합니다. 그런 다음이 목록이 분리되고 새로운 결과 목록이 반환됩니다.

발전기 내재와 발전기는 일반적으로 다른 작업 방식을가집니다. 이 코드 블록은 기본적으로 코드 블록으로, 더 많은 데이터를 요청할 때까지 일시 중지됩니다. 다음과 같이

효과에서, 당신은 발전기를 만들 :

g = (p for p in (1,2,3,4,5,0,6) if 100/p) 

이제 당신이 요청 그렇게 할 때 값을 생성하는 발전기가의 "규칙"에 따라 당신이 준 그것.

발전기를 보유한 즉시 여러 가지 방법으로 n 개의 항목을 얻을 수 있습니다. 다음과 같이

당신은 루프에 대한 간단한을 작성할 수

물론
results = [] 
for x in range(3): # n = 3 in your case 
    results.append(next(g)) 

, 즉 파이썬 없습니다.목록을 원한다고 가정하면 다음과 같이 목록 이해를 사용할 수 있습니다.

results = [next(g) for x in range(3)] 

이것은 "수동으로"수행하는 방법입니다.

import itertools 
results = list(itertools.islice(g, 4)) 

을 그리고 거기입니다 : 당신은 또한 itertools 모듈 (Documentation here)에서 islice 기능을 사용할 수 있습니다. 생성기는 꽤 유용합니다. 상태를 요청하고 기억할 때 실행되는 코드 블록은 정말 가치가 있습니다.

+0

괄호는 '<>'입니다. '[]'것들은 대괄호, 또는 당신이 어디에서 왔는지에 따라 괄호라고 부릅니다. – user2357112

+0

@ user2357112 : 매우 사실입니다. 감사합니다. – user357269

1

이지만 발전기 함축 가능합니다 : 브래킷의

from itertools import islice 
foo = list(islice((p for p in (1,2,3,4,5,0,6) if 100/p), 4)) 

주의 부족 :

0

내장 필터와 islice의 조합을 사용하면 원하는 것을 얻을 수 있습니다. 예.

length = 3 
items_iter = islice(filter(None, [1, 2, 0, 4, 5]), length) # returns a lazy iterator 
items = list(items_iter) 
assert items == [1, 2, 5] 

그러나 자신 만의 생성기를 쓸 수도 있습니다. 생성자 함수는 단일 결과를 반환하는 대신 연속적인 항목을 생성합니다. 때로는 항목을 생성하지 않을 수도 있고 때로는 무한 수의 항목을 생성 할 수도 있습니다. 사례에 대한 예는 다음과 같습니다.

def take_first_n_that_pass(test, length, iterator): 
    i = 0 
    for item in iterator: 
     if i >= length: 
      return # stops generator 
     if test(item): 
      yield item 
      i += 1 
    # end of iterator -- generator stops here as well 

items_iter = take_first_n_that_pass(bool, 3, [0, 1, 2, 0, 4, 5]) 
items = list(items_iter) 
assert items == [1, 2, 4] 
관련 문제