엄청난 수의 항목이있는 목록이 있다고 가정합니다.
l = [ 1, 4, 6, 30, 2, ... ]
항목이 특정 조건을 충족해야하는 목록에서 항목 수를 가져오고 싶습니다. 내 첫 생각은 :
count = len([i for i in l if my_condition(l)])
그러나 my_condition () 필터링 된 목록에도 많은 항목이있는 경우 필터링 된 결과에 대한 새 목록을 만드는 것은 메모리 낭비 일 뿐이라고 생각합니다. 효율성을 위해 IMHO는 위의 호출이 다음보다 나을 수 없습니다.
count = 0
for i in l:
if my_condition(l):
count += 1
임시 목록을 생성하지 않고 특정 조건을 충족하는 항목 수를 얻는 기능적 스타일의 방법이 있습니까?
미리 감사드립니다.
답변
생성기 표현식을 사용할 수 있습니다 .
>>> l = [1, 3, 7, 2, 6, 8, 10]
>>> sum(1 for i in l if i % 4 == 3)
2
또는
>>> sum(i % 4 == 3 for i in l)
2
그 사실을 사용합니다 int(True) == 1
.
또는 itertools.imap
(python 2) 또는 간단히 map
(python 3) 사용할 수 있습니다 .
>>> def my_condition(x):
... return x % 4 == 3
...
>>> sum(map(my_condition, l))
2
답변
당신은 원하는 발전기 이해 보다는 여기에 목록을.
예를 들면
l = [1, 4, 6, 7, 30, 2]
def my_condition(x):
return x > 5 and x < 20
print sum(1 for x in l if my_condition(x))
# -> 2
print sum(1 for x in range(1000000) if my_condition(x))
# -> 14
또는 사용하십시오 itertools.imap
(명시 적 목록 및 생성기 표현식이 다소 파이썬 적이라고 생각하지만).
sum
예제에서는 명확하지 않지만 생성기 이해를 멋지게 구성 할 수 있습니다. 예를 들면
inputs = xrange(1000000) # In Python 3 and above, use range instead of xrange
odds = (x for x in inputs if x % 2) # Pick odd numbers
sq_inc = (x**2 + 1 for x in odds) # Square and add one
print sum(x/2 for x in sq_inc) # Actually evaluate each one
# -> 83333333333500000
이 기술의 멋진 점은 최종 결과가 평가 될 때까지 메모리에 평가 및 저장을 강요하지 않고도 코드에서 개념적으로 별도의 단계를 지정할 수 있다는 것입니다.
답변
reduce
함수형 프로그래밍을 선호하는 경우이를 사용하여 수행 할 수도 있습니다.
reduce(lambda count, i: count + my_condition(i), l, 0)
이렇게하면 한 번만 통과하고 중간 목록이 생성되지 않습니다.
답변
다음과 같이 할 수 있습니다.
l = [1,2,3,4,5,..]
count = sum(1 for i in l if my_condition(i))
조건을 충족하는 각 요소에 대해 1을 더합니다.
답변
from itertools import imap
sum(imap(my_condition, l))