목록 이해:각 항목에 대해 두 개 이상의 항목 반환
목록 이해에서 각 항목에 대해 2개 이상의 항목을 반품할 수 있습니까?
내가 원하는 것(예:
[f(x), g(x) for x in range(n)]
돌아와야 할[f(0), g(0), f(1), g(1), ..., f(n-1), g(n-1)]
그래서 이 코드 블록을 대체할 무언가가 있습니다.
result = list()
for x in range(n):
result.add(f(x))
result.add(g(x))
이중 목록 이해:
[f(x) for x in range(5) for f in (f1,f2)]
데모:
>>> f1 = lambda x: x
>>> f2 = lambda x: 10*x
>>> [f(x) for x in range(5) for f in (f1,f2)]
[0, 0, 1, 10, 2, 20, 3, 30, 4, 40]
>>> from itertools import chain
>>> f = lambda x: x + 2
>>> g = lambda x: x ** 2
>>> list(chain.from_iterable((f(x), g(x)) for x in range(3)))
[2, 0, 3, 1, 4, 4]
타이밍:
from timeit import timeit
f = lambda x: x + 2
g = lambda x: x ** 2
def fg(x):
yield f(x)
yield g(x)
print timeit(stmt='list(chain.from_iterable((f(x), g(x)) for x in range(3)))',
setup='gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2')
print timeit(stmt='list(chain.from_iterable(fg(x) for x in range(3)))',
setup='gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2')
print timeit(stmt='[func(x) for x in range(3) for func in (f, g)]',
setup='gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2')
print timeit(stmt='list(chain.from_iterable((f(x), g(x)) for x in xrange(10**6)))',
setup='gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2',
number=20)
print timeit(stmt='list(chain.from_iterable(fg(x) for x in xrange(10**6)))',
setup='gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2',
number=20)
print timeit(stmt='[func(x) for x in xrange(10**6) for func in (f, g)]',
setup='gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2',
number=20)
2.69210777094
3.13900787874
1.62461071932
25.5944058287
29.2623711793
25.7211849286
sum( ([f(x),g(x)] for x in range(n)), [] )
이는 다음과 같습니다.[f(1),g(1)] + [f(2),g(2)] + [f(3),g(3)] + ...
다음과 같이 생각할 수도 있습니다.
def flatten(list):
...
flatten( [f(x),g(x)] for x in ... )
참고: 올바른 방법은 다음을 사용하는 것입니다.itertools.chain.from_iterable
또는 이중 목록 이해.(모든 +의 목록을 다시 만들 필요가 없으므로 O(N^2) 성능이 아닌 O(N) 성능을 갖습니다.)계속 쓸게요.sum(..., [])
빠른 원-라이너를 원하거나 급할 때, 또는 조합되는 항의 수가 제한되어 있을 때(예: <= 10).그것이 제가 아직도 여기서 이 주의사항을 언급하는 이유입니다.튜플을 사용할 수도 있습니다.((f(x),g(x)) for ...), ()
(또는 khachik의 코멘트에 따라, 2개의 tup을 산출하는 발전기 fg(x))를 갖습니다.)
OP가 목록 이해 솔루션을 찾고 있다는 것을 알고 있지만 다음을 사용하여 대안을 제시하고자 합니다.list.extend()
.
f = lambda x: x
g = lambda x: 10*x
result = []
extend = result.extend
for x in range(5):
extend((f(x),g(x)))
이중 목록 이해를 사용하는 것보다 약간 빠릅니다.
nums = range(100000)
def double_comprehension():
return [func(x) for x in nums for func in (f,g)]
def list_extend():
result = []
extend = result.extend
for x in nums:
extend((f(x),g(x)))
return result
%timeit -n100 double_comprehension()
23.4 ms ± 67 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit -n100 list_extend()
20.5 ms ± 213 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
파이썬 버전: 3.8.0
이 람다 함수는 두 개의 목록을 하나로 압축합니다.
zipped = lambda L1, L2: [L[i]
for i in range(min(len(L1), len(L2)))
for L in (L1, L2)]
예:
>>> f = [x for x in range(5)]
>>> g = [x*10 for x in range(5)]
>>> zipped(f, g)
[0, 0, 1, 10, 2, 20, 3, 30, 4, 40]
축소를 사용한 솔루션:
from functools import reduce
f = lambda x: f"f({x})" ## Just for example
g = lambda x: f"g({x})"
data = [1, 2, 3]
reduce(lambda acc, x: acc + [f(x), g(x)], data, [])
# => ['f(1)', 'g(1)', 'f(2)', 'g(2)', 'f(3)', 'g(3)']
이것이 문제에 접근하는 기능적인 방법입니다.리스트 이해는 본질적으로 다른 방법입니다.map
데이터를 넘겨야 하지만 입력과 출력 사이에 일대일 매핑이 되지 않는 이 경우와 같은 경우에는reduce
출력을 생성하는 방법에 대해 약간의 자유 재량권을 허용합니다.
일반적으로 아무for
양식 구현:
result = []
for n in some_data:
result += some_operation()
## etc.
(즉, 리스트 또는 유사한 데이터 구조에 부작용을 발생시키는 루프의 경우, 누적기 패턴)
선언문으로 리팩터링할 수 있음map/reduce/filter
실행.
합리적으로 가능하다면 두 가지를 사용하는 것보다 사용하는 것을 선호해야 합니다.for
일람표의 절Google Python Style Guide와 같은 일부 스타일 가이드는 여러 개를 사용하는 것을 금지합니다.for
일람표의 절이 방법을 명시적으로 금지하지 않은 스타일 가이드를 사용할 수도 있지만, 다음과 같은 작업을 수행하면 이해력을 더욱 간결하게 만들 수 있습니다.
from itertools import product
result = [y(x) for y, x in product(range(n), (f, g))]
세상에, 비탄!왜 이 모든 양고기들, 납작한 것들, 지퍼들, 그리고 셈들?이것이 가장 간단하고 읽을 수 있는 것이 아닌가요?
>>> [v
... for x in range(5)
... for v in (2 * x,
... 2 * x + 1)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
두 ()로.f(x)
그리고.g(x)
(든)
언급URL : https://stackoverflow.com/questions/11868964/list-comprehension-returning-two-or-more-items-for-each-item
'source' 카테고리의 다른 글
CSS에서 자녀에게 부모의 곡선 경계선을 지키도록 강요 (0) | 2023.10.01 |
---|---|
"네트워크 서비스" 계정을 위해 파워셸에서 윈도우 서비스를 만드는 방법은? (0) | 2023.10.01 |
IntelliJ/Android Studio의 파일 하나에 잘못된 파일 연결 (0) | 2023.10.01 |
리눅스에서 현재 프로세스 이름을 가져오는 방법? (0) | 2023.10.01 |
jQuery 대화 상자 단추에 CSS 적용 (0) | 2023.09.21 |