소개
목록 이해를 사용하면 소스 목록을 쉽게 가져오고 표현식을 적용하여 파생 목록을 얻을 수 있습니다. 예를 들어 목록의 각 요소에 5를 곱하고 싶다고 가정해 보겠습니다. 여기서는 간단한 for 루프를 사용하여 이 작업을 수행합니다.
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] multiply_by_5 = [] for x in a: multiply_by_5.append(x*5) print(f"Output \n *** {multiply_by_5}")
출력
*** [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
목록 이해를 사용하면 반복할 표현식과 입력 시퀀스를 지정하여 동일한 결과를 얻을 수 있습니다.
# List comprehension multiply_by_5 = [x*2 for x in a] print(f"Output \n *** {multiply_by_5}")
출력
*** [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
이제 추가할 목록이 몇 개 있다고 가정해 보겠습니다.
# 1 . Create a List of Numbers list1 = [100, 200, 300, 400] list2 = [500, 600, 700, 800] # 2. Add the two lists to create a new list list3 = [] # Using a Loop. for i in range(len(list1)): added_value = list1[i] + list2[i] list3.append(added_value) print(f"Output \n*** {list3}")
출력
*** [600, 800, 1000, 1200]
이제 여기서 중요한 것은 추가된 값의 파생 목록(여기서는 list3)에 있는 항목이 인덱스를 통해 소스 목록에 있는 항목과 직접적으로 관련되어 있다는 것입니다.
이제 압축이 진행되는 한 동일한 목록 정수에 대한 압축 솔루션이 있습니다. 이 경우 두 개의 정수 목록이 있습니다. 하나는 100, 200, 300, 400을 포함하고 다른 하나는 500, 600, 700, 800을 포함합니다. 물론, 우리는 그것들을 정의하고 변수에 할당할 수 있습니다. 목록이 필요하지 않습니다.
튜플과 같은 다른 시퀀스일 수 있습니다.
그래서 우리가 할 일은 그것들의 요소 쌍을 함께 압축하는 것이므로 list1의 100개와 list2의 500개는 함께 압축되는 식입니다. 각 튜플에 대해 반복하면서 튜플을 변수 및 b로 압축을 풉니다.
list4 = [] list4 = [(a + b) for a, b in zip(list1, list2)] print(f"Output \n*** {list4}")
출력
*** [600, 800, 1000, 1200]
이제 위의 솔루션이 정말 멋져 보이지만 코드에 적용하기 전에 알아야 할 심각한 문제가 있습니다.
zip 내장 함수는 입력 반복자의 길이가 다른 경우 이상하게 작동합니다. 시도해 보겠습니다.
# add a new number to the list list1.append(1000) print(f"Output \n*** Length of List1 is {len(list1)} , Length of List2 is {len(list2)}") # run the zip against the list for addition. list5 = [(a + b) for a, b in zip(list1, list2)] print(f"*** {list5}")
출력
*** Length of List1 is 9 , Length of List2 is 4 *** [600, 800, 1000, 1200]
이제 list3에서 추가된 각 번호를 인쇄할 때 list1에 추가된 번호가 누락되었음을 알 수 있습니다. 추가한 번호는 list1에 있고 zip의 출력에는 표시되지 않습니다.
그리고 이것이 바로 zip이 작동하는 방식입니다. 반복자 중 하나가 소진될 때까지 튜플을 유지합니다. 따라서 list1이 list2에 비해 더 가야 할 것이 있지만 먼저 소진되어 루프가 종료됩니다.
놀랍게도, 당신은 어떤 예외도 통지받지 않습니다. 따라서 프로덕션에서는 zip에 매우 주의해야 합니다.
이 문제에 대한 옵션은 zip long이라는 itertools의 python 함수에 있습니다.
이 zip이 가장 긴 것은 반복자 중 하나가 소진된 경우에도 계속 진행됩니다.
from itertools import zip_longest list6 = [] for a, b in zip_longest(list1, list2): if b is None: print(f" << do your logic here >> ") elif a is None: print(f" << do your logic here >> ") else: list6.append(a + b) print(f"Output \n*** {list6}")
<< do your logic here >> << do your logic here >> << do your logic here >> << do your logic here >> << do your logic here >>
출력
*** [600, 800, 1000, 1200]
결론:
-
여러 반복자를 병렬로 반복하려는 경우 zip 함수가 매우 편리합니다.
-
zip 함수는 길이가 다른 반복자를 전달할 때 다르게 작동합니다.
-
길이가 다른 반복자를 사용하려면 zip_longest를 사용하세요.