2012-05-19 5 views
97

나는 20000 개의 목록과 같은 목록으로 구성되어있다. 각 목록의 세 번째 요소를 플래그로 사용합니다. 나는만큼 적어도 하나 개의 원소의 플래그가 0으로,이 같은의이 목록에 일부 작업을 수행 할 : 태초에 목록의 모든 요소가 조건과 일치하는지 확인하는 방법?

my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....] 

모든 플래그가 0 내가 확인하기 위해 while 루프를 사용할 수 있습니다 적어도 하나 개의 원소의 경우 플래그가 0 :

def check(lista): 
    for item in lista: 
     if item[2] == 0: 
      return True 
    return False 

check(my_list)하면 반환 True, 나는 내 목록 작업을 계속 :

while check(my_list): 
    for item in my_list: 
     if condition: 
      item[2] = 1 
     else: 
      do_sth() 

이 사실 나는을 my_list에서 요소를 제거하고 싶어 나는 반복으로 그 위에 반복하지만 항목을 제거 할 수는 없습니다. 내가 그 위에, 나는 이러한 플래그를 발명 한 반복으로 내가 요소를 제거 할 수 있기 때문에

my_list = [["a", "b"], ["c", "d"], ["e", "f"], .....] 

:

원본을 my_list는 플래그를 가지고 있지 않았다. 그러나 my_list에는 많은 항목이 포함되어 있으며 while 루프는 각각 for 루프에서 모든 루프를 읽으며 많은 시간을 소비합니다! 의견 있으십니까?

+2

보인다.문맥을 좀 더 설명해 주면 더 적절한 것을 제안 할 수 있습니다. – uselpa

+0

아마도 목록을 제거하는 대신 목록을 반복 할 때 항목을 '없음'또는 '[]'로 바꿀 수 있습니다. 'check()'를 사용하여 내부 목록에서 각 항목을 반복하기 전에 전체 목록을 반복 검사하는 것은 매우 느린 방법입니다. – martineau

답변

211

가장 좋은 대답은 all()입니다.이 상황에 대한 기본 제공입니다. 우리는 이것을 generator expression과 결합하여 원하는 결과를 깔끔하고 효율적으로 만듭니다. 예를 들면 :

>>> items = [[1, 2, 0], [1, 2, 0], [1, 2, 0]] 
>>> all(item[2] == 0 for item in items) 
True 
>>> items = [[1, 2, 0], [1, 2, 1], [1, 2, 0]] 
>>> all(item[2] == 0 for item in items) 
False 

을 그리고, 자신의 필터, 예를 들어, 지능형리스트 :

>>> [x for x in items if x[2] == 0] 
[[1, 2, 0], [1, 2, 0]] 

검사 할 경우 적어도 하나의 요소가 더 나은 옵션은 더 any()을 사용하는 것입니다, 0 판독 :

>>> any(item[2] == 0 for item in items) 
True 
+0

람다 사용에 대한 제 잘못, 파이썬의 모든 함수가 Haskell 외의 첫 번째 인수로 받아 들여지지 않습니다. 알., 나는 또한 목록 이해력에 대한 나의 대답을 바꿨다. :) –

+2

@HampusNilsson 목록 이해력은 생성자 표현식과 다릅니다. 'all()'과'any()'단락으로, 예를 들어, 내 첫 번째 값이'False'로 평가되면'all()'은 실패하고 더 이상 값을 체크하지 않고'False'를 반환합니다. 귀하의 예제는 동일한 비교를 수행합니다. 단, 비교 목록 전체가 생성되므로 아무 것도 처리하지 않아도됩니다. –

5

itertools의 takewhile을 이와 같이 사용할 수 있습니다. 조건이 충족되면 구문이 실패하면 중지됩니다. 당신이 목록에있는 항목이 조건을 사용 all 위반 여부를 확인하려면 그 반대의 방법은

for x in itertools.takewhile(lambda x: x[2] == 0, list) 
    print x 
3

dropwhile 것 :

if all([x[2] == 0 for x in lista]): 
    # Will run if all elements in the list has x[2] = 0 (use not to invert if necessary) 

이 일치하지 않는 모든 요소를 ​​제거하려면를 사용 filter

# Will remove all elements where x[2] is 0 
listb = filter(lambda x: x[2] != 0, listb) 
0

all()이 방법을 사용하는 것보다 좀 더 유연하다 :

my_list = [[1, 2, 0], [1, 2, 0], [1, 2, 0]] 
all_zeros = False if False in [x[2] == 0 for x in my_list] else True 
any_zeros = True if True in [x[2] == 0 for x in my_list] else False 
0

또 다른 방법은 itertools.ifilter입니다. 데이터 구조가 문제 적합하지 않습니다처럼 (lambda 사용)이 검사 truthiness 및 프로세스

메가 샘플

for x in itertools.ifilter(lambda x: x[2] == 0, my_list): 
    print x 
관련 문제