Python은 매우 다양하고 강력한 프로그래밍 언어입니다! 문제를 해결해야 할 경우 다양한 접근 방식이 있습니다. 이번 글에서는 List Comprehension에 대해 설명하겠습니다. 어떻게 사용하는지 논의해 볼까요? 언제 사용해야 하거나 사용하면 안 됩니까?
List Comprehension은 기존 목록을 기반으로 목록을 만드는 구문 구조입니다. 목록을 만드는 다양한 구현을 살펴보겠습니다.
루프는 목록을 만드는 전통적인 방법입니다. 어떤 종류의 루프를 사용하든 관계 없습니다. 이런 방식으로 목록을 생성하려면 다음을 수행해야 합니다.
numbers = [] for number in range(10): numbers.append(number) print(numbers)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
이 예에서는 빈 숫자 목록을 인스턴스화합니다. 그런 다음 for 루프를 사용하여 range(10)를 반복하고append() 메서드를 사용하여 목록 끝에 각 숫자를 추가합니다.
map()은 목록을 만드는 또 다른 방법입니다. map()에 함수와 반복 가능한 객체를 전달한 후 객체를 생성해야 합니다. 이 객체에는 지정된 함수를 사용하여 각 반복 요소를 실행하여 얻은 출력이 포함됩니다.
예를 들어, 특정 제품의 가격에 VAT를 추가하는 작업이 제공됩니다.
VAT_PERCENT = 0.1# 10% def add_vat(price): return price + (price * VAT_PERCENT) prices = [10.03, 8.6, 32.85, 41.5, 22.64] grand_prices = map(add_vat, prices) print(grand_prices) grand_prices = list(grand_prices) print(grand_prices)
add_vat() 함수를 빌드하고 가격 반복 가능 객체를 생성했습니다. 두 인수를 모두 map()에 전달하고 결과 지도 객체 grand_prices를 수집하거나 list()를 사용하여 이를 목록으로 쉽게 변환할 수 있습니다.
이제 List Comprehension 접근 방식을 살펴보겠습니다! 이것은 실제로 Pythonic이며 목록을 만드는 더 좋은 방법입니다. 이 접근 방식이 얼마나 강력한지 확인하기 위해 한 줄의 코드로 루프 예제를 다시 작성해 보겠습니다.
numbers = [number for number in range(10)] print(numbers)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
보시다시피 이건 정말 놀라운 방법이에요! 목록 이해는 한 줄 이상의 코드를 작성할 필요가 없을 정도로 읽기 쉬워 보입니다.
목록을 더 잘 이해하려면 다음 구문 형식을 확인하세요.
new_list = [expression for member in iterable]
좋아요, 우리는 루프, map() 및 목록 이해를 사용하여 목록을 만드는 방법을 배웠습니다. 방법이 더 효과적이다'라는 생각이 들 수도 있습니다. 분석해보자!
import random import timeit VAT_PERCENT = 0.1 PRICES = [random.randrange(100) for x in range(100000)] def add_vat(price): return price + (price * VAT_PERCENT) def get_grand_prices_with_map(): return list(map(add_vat, PRICES)) def get_grand_prices_with_comprehension(): return [add_vat(price) for price in PRICES] def get_grand_prices_with_loop(): grand_prices = [] for price in PRICES: grand_prices.append(add_vat(price)) return grand_prices print(timeit.timeit(get_grand_prices_with_map, number=100)) print(timeit.timeit(add_grand_prices_with_comprehension, number=100)) print(timeit.timeit(get_grand_prices_with_loop, number=100))
0.9833468980004909# with_map 1.197223742999995 # with_comprehension 1.3564663889992516# with_loop
지금 볼 수 있듯이 목록을 만드는 가장 좋은 방법은 map()이고, 두 번째로 좋은 방법은 목록 이해, 그리고 마지막으로 루프입니다.
그러나 방법 선택은 달성하려는 목표에 따라 달라져야 합니다.
앞서 이 공식을 보여드렸습니다.
new_list = [expression for member in iterable]
공식이 약간 불완전할 수 있습니다. 분석 표현식에 대한 보다 완전한 설명에는 선택적 조건에 대한 지원이 추가됩니다. 목록 이해에 조건부 논리를 추가하는 가장 일반적인 방법은 표현식 끝에 조건부를 추가하는 것입니다.
new_list = [expression for member in iterable (if conditional)]
여기서 조건문은 오른쪽 대괄호 안에 있습니다.
조건은 List Comprehension이 원치 않는 값을 필터링할 수 있도록 허용하기 때문에 중요합니다. 일반적인 경우 filter()를 호출하여 수행할 수도 있습니다.
numbers = [number for number in range(20) if number % 2 == 0] print(numbers)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
보시다시피 이 Comprehension은 사용할 수 있는 값을 수집합니다. by 2 나누어지고 나머지가 없는 수입니다.
더 복잡한 필터가 필요한 경우 조건부 논리를 별도의 함수로 이동할 수도 있습니다.
def is_prime(number): if number > 1: for el in range(2, int(number/2)+1): if (number % el) == 0: return False else: return True numbers = [number for number in range(20) if is_prime(number)] print(numbers)
[2, 3, 5, 7, 11, 13, 17, 19]
is_prime(number)을 구성하여 숫자가 소수인지 확인하고 부울 값을 반환합니다. 다음으로 분석 표현식의 조건에 함수를 추가해야 합니다.
이 공식을 사용하면 조건부 논리를 사용하여 여러 가지 가능한 출력 옵션 중에서 선택할 수 있습니다. 예를 들어, 제품 가격표가 있고 음수가 있는 경우 이를 양수로 변환해야 합니다.
price_list = [1.34, 19.01, -4.2, 6, 8.78, -1,1] normalized_price_list = [price if price > 0 else price*-1 for price in price_list] print(normalized_price_list)
[1.34, 19.01, 4.2, 6, 8.78, 1,1]
여기서 표현식 가격에는 조건문이 있습니다. if 가격 > 0 else 가격*-1. 이는 가격이 양수이면 가격 값을 출력하고, 가격이 음수이면 가격을 양수 값으로 변환하도록 Python에 지시합니다. 이 기능은 강력하며 조건부 논리를 자체 기능으로 생각하면 정말 유용합니다.
def normalize_price(price): return price if price > 0 else price*-1 price_list = [1.34, 19.01, -4.2, 6, 8.78, -1,1] normalized_price_list = [normalize_price(price) for price in price_list] print(normalized_price_list)
[1.34, 19.01, 4.2, 6, 8.78, 1,1]
您还可以创建一个集合解析式!它基本与列表解析式相同。不同之处在于集合解析式不包含重复项。您可以通过使用花括号取代方括号来创建集合解析式:
string = "Excellent" unique_string = {letter for letter in string} print(unique_string)
{"E", "e", "n", "t", "x", "c", "l"}
你的集合解析式只包含唯一的字母。这与列表不同,集合不保证项目将以特定顺序存储数据。这就是为什么集合输出的第二个字母是 e,即使字符串中的第二个字母是 x。
字典解析式也是是类似的,但需要定义一个键:
string = "Words are but wind" word_order = {el: ind+1 for ind, el in enumerate(string.split())} print(word_order)
{"Words": 1, "are": 2, "but": 3, "wind": 4}
要创建 word_order 字典,请在表达式中使用花括号 ({}) 以及键值对 (el: ind+1)。
Python 3.8 中引入的海象运算符允许您一次解决两个问题:为变量赋值,返回该值。
假设您需要对将返回温度数据的 API 应用十次。您想要的只是 100 华氏度以上的结果。而每个请求可能都会返回不同的数据。在这种情况下,没有办法在 Python 中使用列表解析式来解决问题。可迭代成员(如果有条件)的公式表达式无法让条件将数据分配给表达式可以访问的变量。
海象运算符解决了这个问题。它允许您在执行表达式的同时将输出值分配给变量。以下示例显示了这是如何实现的,使用 get_weather_data() 生成伪天气数据:
import random def get_weather_data(): return random.randrange(90, 110) hot_temps = [temp for item in range(20) if (temp := get_weather_data()) >= 100] print(hot_temps)
[108, 100, 106, 103, 108, 106, 103, 104, 109, 106]
列表解析式非常有用,它可以帮助您编写清晰且易于阅读和调试的代码。但在某些情况下,它们可能会使您的代码运行速度变慢或使用更多内存。如果它让您的代码效率更低或更难理解,那么可以考虑选择另一种方式。
可以通过嵌套解析式以创建列表、字典和集合的组合集合(译者注:这个集合不是指 set 对象类型,而是 collection,泛指容器)。例如,假设一家公司正在跟踪一年中五个不同城市的收入。存储这些数据的完美数据结构可以是嵌套在字典解析式中的列表解析式。
cities = ['New York', 'Oklahoma', 'Toronto', 'Los Angeles', 'Miami'] budgets = {city: [0 for x in range(12)] for city in cities} print(budgets)
{ "NewYork": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "Oklahoma": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "Toronto": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "LosAngeles": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "Miami": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
您使用字典解析式创建了 budgets 容器。该表达式是一个键值对,其中包含另一个解析式。此代码将快速生成城市中每个 city 的数据列表。
嵌套列表是创建矩阵的常用方法,通常用于数学目的。查看下面的代码块:
matrix = [[x for x in range(7)] for y in range(6)] print(matrix)
[ [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6] ]
外部列表解析式 [... for y in range(6)] 创建了六行,而内部列表解析式 [x for x in range(7)] 将用值填充这些行中的每一行。
到目前为止,每个嵌套解析式的目标都是真正且直观的。但是,还有一些其他情况,例如创建扁平化的嵌套列表,其中的逻辑可以使您的代码非常难以阅读。让我们看下面的例子,使用嵌套列表解析式来展平一个矩阵:
matrix = [ [0, 1, 0], [1, 0, 1], [2, 1, 2], ] flat = [num for row in matrix for num in row] print(flat)
[0, 1, 0, 1, 0, 1, 2, 1, 2]
扁平化矩阵的代码确实很简洁,但是太难理解了,您应该花点时间弄清楚它是如何工作的。另一方面,如果您使用 for 循环来展平相同的矩阵,那么您的代码将更加简单易读:
matrix = [ [0, 1, 0], [1, 0, 1], [2, 1, 2], ] flat = [] for row in matrix: for num in row: flat.append(num) print(flat)
[0, 1, 0, 1, 0, 1, 2, 1, 2]
现在,您可以看到代码一次遍历矩阵的一行,在移动到下一行之前取出该行中的所有元素。
虽然嵌套列表解析式可能看起来更具有 Python 风格,但对于能够编写出您的团队可以轻松理解和修改的代码来才是更加最重要的。当选择一个方法时,您应该根据解析式是有助于还是有损于可读性来做出相应的判断。
Python 中的列表解析式通过将整个列表存储到内存中来工作。对于小型至中型列表这通常很好。如果您想将前一千个整数相加,那么列表解析式将轻松地解决此任务:
summary = sum([x for x in range(1000)]) print(summary)
499500
但是,如果您需要对十亿个数字求和呢?您可以尝试执行此操作,但您的计算机可能不会有响应。这是可能因为计算机中分配大量内存。也许您是因为计算机没有如此多的内存资源。
例如,你想要一些第一个十亿整数,那么让我们使用生成器!这可能多需要一些时间,但计算机应该可以克服它:
summary = sum((x for x in range(1000000000))) print(summary)
499999999500000000
让我们来对比一下哪种方法是更优的!
import timeit def get_sum_with_map(): return sum(map(lambda x: x, range(1000000000))) def get_sum_with_generator(): return sum((x for x in range(1000000000))) print(timeit.timeit(get_sum_with_map, number=100)) print(timeit.timeit(get_sum_with_generator, number=100))
4940.844053814# get_sum_with_map 3464.1995523349997# get_sum_with_generator
正如您所见,生成器比 map() 高效得多。
本文向您介绍了列表解析式,以及如何使用它来解决复杂的任务,而不会使您的代码变得过于困难。
이제 당신은:
위 내용은 Python 목록 분석을 사용하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!