부울 목록을 기준으로 목록 필터링
부울 목록 내의 값이 지정된 경우 필터링해야 하는 값 목록이 있습니다.
list_a = [1, 2, 4, 6]
filter = [True, False, True, False]
다음 행으로 필터링된 새 목록을 생성합니다.
filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]
그 결과, 다음과 같습니다.
print filtered_list
[1,4]
라인은 작동하지만 (내 눈에는) 좀 과해 보여서 같은 일을 할 수 있는 더 간단한 방법이 없을까 생각했다.
어드바이스
아래 답변에서 제시된 두 가지 유용한 조언의 요약:
1-목록 이름 지정 안 함filter
내장된 기능이기 때문에 제가 했던 것처럼요.
2 - 비교하지 말 것True
에서 했던 것처럼if filter[idx]==True..
필요없으니까.사용하고 있는 것만으로if filter[idx]
충분합니다.
다음 항목을 찾고 있습니다.
>>> from itertools import compress
>>> list_a = [1, 2, 4, 6]
>>> fil = [True, False, True, False]
>>> list(compress(list_a, fil))
[1, 4]
타이밍 비교(py3.x):
>>> list_a = [1, 2, 4, 6]
>>> fil = [True, False, True, False]
>>> %timeit list(compress(list_a, fil))
100000 loops, best of 3: 2.58 us per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v] #winner
100000 loops, best of 3: 1.98 us per loop
>>> list_a = [1, 2, 4, 6]*100
>>> fil = [True, False, True, False]*100
>>> %timeit list(compress(list_a, fil)) #winner
10000 loops, best of 3: 24.3 us per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v]
10000 loops, best of 3: 82 us per loop
>>> list_a = [1, 2, 4, 6]*10000
>>> fil = [True, False, True, False]*10000
>>> %timeit list(compress(list_a, fil)) #winner
1000 loops, best of 3: 1.66 ms per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v]
100 loops, best of 3: 7.65 ms per loop
사용하지 않다filter
변수 이름으로서 빌트인 함수입니다.
다음과 같은 경우:
filtered_list = [i for (i, v) in zip(list_a, filter) if v]
사용.zip
인덱싱 없이 여러 시퀀스에 걸쳐 병렬로 반복하는 피톤식 방법입니다.이것은, 양쪽 시퀀스의 길이가 같은 것을 전제로 하고 있습니다(최단 기한이 지나면 zip이 정지합니다).사용.itertools
그런 간단한 경우는 좀 과잉 살상입니다...
이 예에서 해야 할 한 가지 작업은 작업을 True와 비교하는 것입니다.이는 보통 필요하지 않습니다.대신if filter[idx]==True: ...
, 간단하게 쓸 수 있습니다.if filter[idx]: ...
.
numpy 포함:
In [128]: list_a = np.array([1, 2, 4, 6])
In [129]: filter = np.array([True, False, True, False])
In [130]: list_a[filter]
Out[130]: array([1, 4])
또는 list_a가 numpy 배열일 수 있지만 필터링할 수 없는 경우 Alex Szatmary의 답변을 참조하십시오.
Numpy는 보통 속도도 크게 향상시킵니다.
In [133]: list_a = [1, 2, 4, 6]*10000
In [134]: fil = [True, False, True, False]*10000
In [135]: list_a_np = np.array(list_a)
In [136]: fil_np = np.array(fil)
In [139]: %timeit list(itertools.compress(list_a, fil))
1000 loops, best of 3: 625 us per loop
In [140]: %timeit list_a_np[fil_np]
10000 loops, best of 3: 173 us per loop
numpy를 사용하여 이를 수행하려면 (어레이가 있는 경우)a
대신list_a
:
a = np.array([1, 2, 4, 6])
my_filter = np.array([True, False, True, False], dtype=bool)
a[my_filter]
> array([1, 4])
filtered_list = [list_a[i] for i in range(len(list_a)) if filter[i]]
그렇게 우아하지는 않지만, 이 솔루션이 더 간단한 구문이라고 생각합니다.이름을 바꿨어요filter
로.filter_
내장 기능과의 충돌을 피하기 위해:
list_a = [1, 2, 4, 6]
filter_ = [True, False, True, False]
해결책은 다음과 같습니다.
index = [i for i in range(len(filter_)) if filter_[i]]
list_a_filtered = [list_a[i] for i in index]
또는 한 줄:
list_a_filtered = [list_a[i] for i in [j for j in range(len(filter_)) if filter_[j]]]
python 3에서는 사용할 수 있습니다.list_a[filter]
갖기 위해True
가치.갖기 위해False
값 사용list_a[~filter]
언급URL : https://stackoverflow.com/questions/18665873/filtering-a-list-based-on-a-list-of-booleans
'programing' 카테고리의 다른 글
LINQ를 사용하여 리스트에서 요소 제거 (0) | 2023.04.14 |
---|---|
gnu cp 명령을 사용하여 파일을 여러 디렉토리에 복사하는 방법 (0) | 2023.04.14 |
다운로드한 Xcode 시뮬레이터를 제거하는 방법 (0) | 2023.04.14 |
swift와 함께 isKindOfClass 사용 (0) | 2023.04.14 |
목표 C에서의 NULL 대 0 (0) | 2023.04.14 |