Nice programing

"if"필터가있는 반복자에 대한 한 줄 for 루프?

nicepro 2021. 1. 10. 19:53
반응형

"if"필터가있는 반복자에 대한 한 줄 for 루프?


어리석은 질문 :
간단한 for 루프와 간단한 if 문이 있습니다.

for airport in airports:
    if airport.is_important:

어떻게 든 이것을 한 줄로 쓸 수 있는지 궁금합니다.
예, 이렇게 할 수 있습니다.

for airport in (airport for airport in airports if airport.is_important):

그러나 그것은 너무 어리 석고 중복됩니다 ( for airport in airport for airport in airports...).
더 좋은 방법이 있습니까?


아니, 더 짧은 길이 없습니다. 일반적으로 두 줄로 나눕니다.

important_airports = (airport for airport in airports if airport.is_important)
for airport in important_airports:
    # do stuff

이것은 더 유연하고 읽기 쉬우 며 여전히 많은 메모리를 소비하지 않습니다.


당신은 할 수 있습니다

for airport in filter(lamdba x: x.is_important, airports):
    # do stuff...

나는 루프에 부정적인 가드를 사용할 것입니다. 읽기 쉽고 추가 수준의 들여 쓰기를 도입하지 않습니다.

for airport in airports:
    if not airport.is_important: continue
    <body of loop>

Mabe 이것, 그러나 그것은 다소 똑같은 장황합니다 ...

import itertools

for airport in itertools.ifilter(lambda x: x.is_important, airports):
    ...

이것은 파이썬의 디자인 철학입니다. 한 줄에 넣기에는 너무 많은 단어가 필요하다면, 당신을 쫓는 사람을 돕기 위해 몇 줄로 나누어야합니다. 목록 및 생성기 표현식은 이터 러블을 제자리에서 변환하여 mapfilter.


다음은 일부 다른 필터 버전에 대한 대안입니다.

from operator import attrgetter as attr
for airport in filter(attr('is_important'), airports):
    ...

이것은 매우 간결하고 점 표기법 attr ( 'first_class.is_full')을 사용할 수있는 장점이 있습니다.

또한 filter_by_attr과 같은 유틸리티 함수에 그런 것 (또는 목록 이해력을 사용하는 버전)을 넣을 수도 있습니다. 그런 다음 할 수 있습니다.

for airport in filter_by_attr(airports, 'is_important'):
    ...

나는 여전히 e-satis가 당신이 사용하는 방법에 관계없이 새로운 변수에 넣는 것이 옳다고 생각합니다. 특히 사용이 해당 속성의 이름과 정확히 일치하지 않는 경우 (또는 기준이 더 복잡한 경우) 더 명확합니다.

이에 대한 유일한 메모는 여러 곳에서 이것을 사용하는 경우 공항을 특별 컬렉션으로 만들어야하며 필터링 된 컬렉션을 반환하는 @property 인 'important_airports'를 사용해야합니다. 또는 필터링을 숨기는 다른 추상화 (예 : 서비스 호출).


목록 이해 사용 (공항이 객체 목록 인 경우에만) :

for airport in [a for a in airports if a.is_important]:

참조 URL : https://stackoverflow.com/questions/2401785/single-line-for-loop-over-iterator-with-an-if-filter

반응형