부작용에 대한 목록 이해력을 사용하는 것이 Pythonic입니까?
반환 값이 아닌 부작용 (화면에 인쇄, GUI 업데이트, 파일로 인쇄 등)이 아닌 부작용으로 호출하는 함수를 생각해보십시오.
def fun_with_side_effects(x):
...side effects...
return y
이제이 func를 호출하기 위해 목록 이해력을 사용하는 것이 Pythonic입니까 ?
[fun_with_side_effects(x) for x in y if (...conditions...)]
목록을 어디에도 저장하지 않습니다.
또는이 func를 다음과 같이 호출해야합니다.
for x in y:
if (...conditions...):
fun_with_side_effects(x)
어느 것이 더 낫고 그 이유는 무엇입니까?
그렇게하는 것은 매우 반 파이 토닉이며 노련한 Pythonista는 당신에게 지옥을 줄 것입니다. 중간 목록은 생성 된 후 버려 지므로 잠재적으로 매우 크고 생성 비용이 많이들 수 있습니다.
사람들이 말했듯이 필요하지 않은 큰 임시 목록을 만들 것이기 때문에 목록 이해력을 사용해서는 안됩니다 . 다음 두 가지 방법은 동일합니다.
consume(side_effects(x) for x in xs)
for x in xs:
side_effects(x)
man 페이지 consume
에서 정의 itertools
:
def consume(iterator, n=None):
"Advance the iterator n-steps ahead. If n is none, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
물론 후자는 더 명확하고 이해하기 쉽습니다.
목록 이해는 목록을 만드는 데 사용됩니다. 그리고 실제로 목록을 작성하지 않는 한 목록 이해를 사용 해서는 안됩니다 .
그래서 두 번째 옵션을 얻었습니다. 목록을 반복 한 다음 조건이 적용될 때 함수를 호출합니다.
두 번째가 더 좋습니다.
코드를 이해해야하는 사람을 생각해보십시오. 첫 번째로 쉽게 업장을 얻을 수 있습니다 :)
filter ()를 사용하여 둘 사이의 중간에 갈 수 있습니다. 예를 고려하십시오.
y=[1,2,3,4,5,6]
def func(x):
print "call with %r"%x
for x in filter(lambda x: x>3, y):
func(x)
목표에 따라 다릅니다.
목록의 각 개체에 대해 몇 가지 작업을 수행하려는 경우 두 번째 방법을 채택해야합니다.
다른 목록에서 목록을 생성하려는 경우 목록 이해를 사용할 수 있습니다.
명시적인 것이 암시적인 것보다 낫습니다. 단순한 것이 복잡한 것보다 낫습니다. (파이썬 젠)
넌 할 수있어
for z in (fun_with_side_effects(x) for x in y if (...conditions...)): pass
하지만 그다지 예쁘지 않습니다.
부작용에 대한 목록 이해력을 사용하는 것은 추악하고 비파이 토닉이며 비효율적이며 저는 그렇게하지 않을 것입니다. for
루프 for
는 부작용이 중요한 절차 적 스타일을 나타 내기 때문에 대신 루프를 사용합니다 .
그러나 부작용에 대한 목록 이해를 절대적으로 사용해야한다면 생성기 표현식을 대신 사용하여 비 효율성을 피해야합니다. 이 스타일을 절대적으로 고집한다면 다음 두 가지 중 하나를 수행하십시오.
any(fun_with_side_effects(x) and False for x in y if (...conditions...))
또는:
all(fun_with_side_effects(x) or True for x in y if (...conditions...))
These are generator expressions, and they do not generate a random list that gets tossed out. I think the all
form is perhaps slightly more clear, though I think both of them are confusing and shouldn't be used.
I think this is ugly and I wouldn't actually do it in code. But if you insist on implementing your loops in this fashion, that's how I would do it.
I tend to feel that list comprehensions and their ilk should signal an attempt to use something at least faintly resembling a functional style. Putting things with side effects that break that assumption will cause people to have to read your code more carefully, and I think that's a bad thing.
'development' 카테고리의 다른 글
교차 조인의 용도는 무엇입니까? (0) | 2020.08.25 |
---|---|
컬렉션에 AddRange (0) | 2020.08.25 |
numpy max 대 amax 대 최대 (0) | 2020.08.25 |
Linux의 디렉토리 아래 새로 생성 된 파일 및 하위 디렉토리에 대한 기본 권한을 설정 하시겠습니까? (0) | 2020.08.25 |
"%. * s"는 printf에서 무엇을 의미합니까? (0) | 2020.08.25 |