Python Language
목록 이해력
수색…
소개
[i ** 2 for i in range(1,11)]
기존 목록 range
의 더미 i
는 새 요소 패턴을 만드는 데 사용됩니다. 표현하기 어려운 언어에서 for 루프가 필요한 곳에서 사용됩니다.
통사론
- [나는 범위 (10) 안에] 기본 목록 이해력
- [내가 xrange (i)에 대한] 파이썬 2.x에서 생성기 개체를 기본 목록 이해 #
- [i가 범위 (20) 인 경우 i % 2 == 0] 필터 사용
- [3, 4, 5]에서 y에 대해 [1, 2, 3에서 x에 대해 x + y] 중첩 된 루프
- [i가 6보다 큰 경우, 범위 (10)의 i에 대해 0] # 3 진 표현
- [if i> 4 else if i for range (20) if i % 2 == 0] 필터 및 삼항 표현식 사용
- [[3, 4, 5]]에서 y에 대한 [[x, y는 [1, 2, 3]에서 x에 대해] 중첩 된 목록 이해력
비고
리스트 comprehension은 PEP 202 에서 개괄되었고 Python 2.0에서 소개되었습니다.
조건부 목록 이해
주어진 목록 이해 하나 이상을 추가 할 수 있습니다 if
조건 값을 필터링 할 수 있습니다.
[<expression> for <element> in <iterable> if <condition>]
<iterable>
각 <element>
에 대해; <condition>
이 True
평가되면 <expression>
(일반적으로 <element>
의 함수)을 반환 된 목록에 추가합니다.
예를 들어, 정수 시퀀스에서 짝수를 추출하는 데 사용할 수 있습니다.
[x for x in range(10) if x % 2 == 0]
# Out: [0, 2, 4, 6, 8]
위의 코드는 다음과 같습니다.
even_numbers = []
for x in range(10):
if x % 2 == 0:
even_numbers.append(x)
print(even_numbers)
# Out: [0, 2, 4, 6, 8]
또한, [e for x in y if c]
식인 [e for x in y if c]
의 조건부 목록 이해 [e for x in y if c]
(여기서 e
와 c
는 x
표현식입니다.)는 list(filter(lambda x: c, map(lambda x: e, y)))
.
동일한 결과를 제공 했음에도 불구하고 이전 예제가 후자보다 거의 2 배 빠르다는 사실에주의하십시오. 호기심이 많은 사람들에게 이것은 이유에 대한 좋은 설명입니다.
이것은 list comprehension의 <expression>
부분에 사용할 수있는 ... if ... else ...
조건식 ( 3 진 표현식 이라고도 함)과는 매우 다른 점에 유의하십시오. 다음 예제를 고려하십시오.
[x if x % 2 == 0 else None for x in range(10)]
# Out: [0, None, 2, None, 4, None, 6, None, 8, None]
조건식은 필터가 아니라 목록 항목에 사용할 값을 결정하는 연산자입니다.
<value-if-condition-is-true> if <condition> else <value-if-condition-is-false>
다른 연산자와 결합하면 더 명확 해집니다.
[2 * (x if x % 2 == 0 else -1) + 1 for x in range(10)]
# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
Python 2.7을 사용하는 경우, xrange
문서에 설명 된 것처럼 xrange
가 여러 가지 이유로 range
보다 우수 할 수 있습니다.
[2 * (x if x % 2 == 0 else -1) + 1 for x in xrange(10)]
# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
위의 코드는 다음과 같습니다.
numbers = []
for x in range(10):
if x % 2 == 0:
temp = x
else:
temp = -1
numbers.append(2 * temp + 1)
print(numbers)
# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
하나는 삼항 표현과 결합 할 if
조건을. 삼항 연산자는 필터링 된 결과에 대해 작업합니다.
[x if x > 2 else '*' for x in range(10) if x % 2 == 0]
# Out: ['*', '*', 4, 6, 8]
삼원 연산자만으로는 같은 결과를 얻을 수 없었습니다.
[x if (x > 2 and x % 2 == 0) else '*' for x in range(10)]
# Out:['*', '*', '*', '*', 4, '*', 6, '*', 8, '*']
또한 : 조건부 목록 내포에 대한 충분한 대안을 제공하는 필터 .
중첩 루프가 포함 된 목록 이해
List Comprehensions 은 중첩 된 for
루프를 사용할 수 있습니다. 목록 내포 내에서 임의의 수의 중첩 된 for 루프를 코딩 할 수 있으며 for
루프마다 선택적 if
관련 if
테스트가있을 수 있습니다. 그렇게 할 때 for
구조의 순서는 일련의 중첩 for
문을 작성할 때와 같은 순서입니다. list comprehensions의 일반적인 구조는 다음과 같습니다.
[ expression for target1 in iterable1 [if condition1]
for target2 in iterable2 [if condition2]...
for targetN in iterableN [if conditionN] ]
예를 들어 다음 for
코드는 for
문을 여러 개 사용하여 목록을 병합합니다.
data = [[1, 2], [3, 4], [5, 6]]
output = []
for each_list in data:
for element in each_list:
output.append(element)
print(output)
# Out: [1, 2, 3, 4, 5, 6]
동등하게 복수와 지능형리스트로 쓸 수 for
구조 :
data = [[1, 2], [3, 4], [5, 6]]
output = [element for each_list in data for element in each_list]
print(output)
# Out: [1, 2, 3, 4, 5, 6]
확장 형식과 목록 이해 모두에서 외부 루프 (첫 번째 문)가 먼저옵니다.
더 소형화 될뿐만 아니라, 중첩 된 이해력도 상당히 빠릅니다.
In [1]: data = [[1,2],[3,4],[5,6]]
In [2]: def f():
...: output=[]
...: for each_list in data:
...: for element in each_list:
...: output.append(element)
...: return output
In [3]: timeit f()
1000000 loops, best of 3: 1.37 µs per loop
In [4]: timeit [inner for outer in data for inner in outer]
1000000 loops, best of 3: 632 ns per loop
위의 함수 호출에 대한 오버 헤드는 약 140ns 입니다.
인라인 if
의 유사 중첩되고, 처음 이후 어느 위치에서 발생할 수있는 for
:
data = [[1], [2, 3], [4, 5]]
output = [element for each_list in data
if len(each_list) == 2
for element in each_list
if element != 5]
print(output)
# Out: [2, 3, 4]
그러나 가독성을 위해 기존 for 루프를 사용하는 것을 고려해야합니다. 중첩이 2 단계 이상 깊거나 이해력의 논리가 너무 복잡 할 때 특히 그렇습니다. 여러 개의 중첩 루프 목록 이해가 오류가 발생하거나 예상치 못한 결과가 발생할 수 있습니다.
리팩토링 필터 및 목록 내재에 매핑
filter
또는 map
기능은 종종 목록 내포 로 대체되어야합니다. 귀도 반 로섬 (Guido Van Rossum) 은 2005 년 공개 서한에서 이를 잘 설명합니다.
filter(P, S)
는 거의 항상[x for x in S if P(x)]
로 명확하게 표시되며, 가장 일반적인 용도는x==42
와 같은 비교어 인 조건부를 포함한다는 큰 이점이 있습니다. 람다는 독자를 위해 훨씬 더 많은 노력을 요구합니다 (람다는 목록 이해보다 느립니다).map(F, S)
는[F(x) for x in S]
됩니다. 물론 많은 경우에 대신 생성기 표현식을 사용할 수 있습니다.
다음 코드 행은 " pythonic이 아닌 "것으로 간주되어 많은 python linters에서 오류를 발생시킵니다.
filter(lambda x: x % 2 == 0, range(10)) # even numbers < 10
map(lambda x: 2*x, range(10)) # multiply each number by two
reduce(lambda x,y: x+y, range(10)) # sum of all elements in list
우리는 이전의 인용에서 배운 것을 가지고 가서, 우리는 이러한 분해 할 수 filter
및 map
자신의 상응하는 지능형리스트로 표현; 또한 각각에서 람다 함수를 제거하여 코드를 프로세스에서 더 읽기 쉽게 만들어줍니다.
# Filter:
# P(x) = x % 2 == 0
# S = range(10)
[x for x in range(10) if x % 2 == 0]
# Map
# F(x) = 2*x
# S = range(10)
[2*x for x in range(10)]
연쇄 기능을 처리 할 때 가독성이 더욱 분명 해집니다. 가독성으로 인해 하나의지도 또는 필터 함수의 결과가 다음 결과로 전달되어야합니다. 단순한 경우에는 단일 목록 이해로 대체 할 수 있습니다. 또한, 우리는 목록 작성에서 프로세스의 결과가 무엇인지, 체인 된 맵 및 필터 프로세스에 대해 추론 할 때 더 많은인지 적로드가있는 곳을 쉽게 알 수 있습니다.
# Map & Filter
filtered = filter(lambda x: x % 2 == 0, range(10))
results = map(lambda x: 2*x, filtered)
# List comprehension
results = [2*x for x in range(10) if x % 2 == 0]
리팩토링 - 빠른 참조
지도
map(F, S) == [F(x) for x in S]
필터
filter(P, S) == [x for x in S if P(x)]
여기서 F
와 P
는 각각 입력 값을 변환하고 bool
반환하는 함수입니다.
중첩 목록 이해
중첩 된 목록 내포는 중첩 루프가있는 목록 내포와 달리 목록 이해 내에서 목록 내포입니다. 초기 표현식은 다른 목록 이해력을 포함하여 임의의 표현식이 될 수 있습니다.
#List Comprehension with nested loop
[x + y for x in [1, 2, 3] for y in [3, 4, 5]]
#Out: [4, 5, 6, 5, 6, 7, 6, 7, 8]
#Nested List Comprehension
[[x + y for x in [1, 2, 3]] for y in [3, 4, 5]]
#Out: [[4, 5, 6], [5, 6, 7], [6, 7, 8]]
중첩 된 예제는 다음과 같습니다.
l = []
for y in [3, 4, 5]:
temp = []
for x in [1, 2, 3]:
temp.append(x + y)
l.append(temp)
중첩 된 이해력을 사용하여 행렬을 조 변경하는 한 가지 예입니다.
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
[[row[i] for row in matrix] for i in range(len(matrix))]
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
중첩 된 for
루프와 마찬가지로 중첩이 될 수있는 방법에 제한이 없습니다.
[[[i + j + k for k in 'cd'] for j in 'ab'] for i in '12']
# Out: [[['1ac', '1ad'], ['1bc', '1bd']], [['2ac', '2ad'], ['2bc', '2bd']]]
목록 내에서 동시에 두 개 이상의 목록 반복
list comprehension 에서 두 개 이상의리스트를 동시에 반복하기 위해, zip()
을 다음과 같이 사용할 수 있습니다 :
>>> list_1 = [1, 2, 3 , 4]
>>> list_2 = ['a', 'b', 'c', 'd']
>>> list_3 = ['6', '7', '8', '9']
# Two lists
>>> [(i, j) for i, j in zip(list_1, list_2)]
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
# Three lists
>>> [(i, j, k) for i, j, k in zip(list_1, list_2, list_3)]
[(1, 'a', '6'), (2, 'b', '7'), (3, 'c', '8'), (4, 'd', '9')]
# so on ...