> 백엔드 개발 > 파이썬 튜토리얼 > Python의 목록 이해가 작업을 해결하는 효율적인 방법입니까?

Python의 목록 이해가 작업을 해결하는 효율적인 방법입니까?

WBOY
풀어 주다: 2023-04-13 22:19:01
앞으로
1540명이 탐색했습니다.

Python의 목록 이해가 작업을 해결하는 효율적인 방법입니까?

Python은 매우 다양하고 강력한 프로그래밍 언어입니다! 문제를 해결해야 할 경우 다양한 접근 방식이 있습니다.

목록 이해의 장점

  • 루프보다 시간과 공간을 절약합니다.
  • 더 적은 코드 줄이 필요합니다.
  • 반복문을 수식으로 변환하세요.

Python에서 목록을 만드는 방법

List Comprehension은 기존 목록을 기반으로 목록을 만드는 구문 구조입니다. 목록을 만드는 다양한 구현을 살펴보겠습니다.

루프

루프는 목록을 만드는 전통적인 방법입니다. 어떤 종류의 루프를 사용하든 관계 없습니다. 이런 방식으로 목록을 생성하려면 다음을 수행해야 합니다.

  1. 빈 목록을 인스턴스화합니다.
  2. 반복 가능한 요소(예: 범위)를 반복합니다.
  3. 각 요소를 목록 끝에 추가하세요.
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()은 목록을 만드는 또 다른 방법입니다. 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()를 사용하여 이를 목록으로 쉽게 변환할 수 있습니다.

출력:

<map object at 0x7f18721e7400># map(add_vat, prices)
[11.03, 9.46, 36.14, 45.65, 24.9]# list(grand_prices)
로그인 후 복사

List comprehension

이제 List comprehension 접근 방식을 살펴보겠습니다! 이것은 실제로 Pythonic이며 목록을 만드는 더 좋은 방법입니다. 이 접근 방식이 얼마나 강력한지 확인하기 위해 한 줄의 코드로 루프 예제를 다시 작성해 보겠습니다.

numbers = [number for number in range(10)]
print(numbers)
로그인 후 복사

Output

[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()이고, 두 번째로 좋은 방법은 목록 이해이고 마지막으로 루프입니다.

그러나 방법 선택은 달성하려는 목표에 따라 달라져야 합니다.

  • map()을 사용하면 코드를 더욱 효율적으로 만들 수 있습니다.
  • 루프를 사용하면 코드 아이디어가 더 명확해질 수 있습니다.
  • 목록 이해를 사용하면 코드를 더 간결하고 효율적으로 만들 수 있습니다. 이는 가장 읽기 쉽기 때문에 목록을 만드는 가장 좋은 방법입니다.

고급 분석 공식

조건부 논리

앞서 이 공식을 보여드렸습니다.

new_list = [expression for member in iterable]
로그인 후 복사
로그인 후 복사

공식이 약간 불완전할 수 있습니다. 분석 표현식에 대한 보다 완전한 설명에는 선택적 조건에 대한 지원이 추가됩니다. 목록 이해에 조건부 논리를 추가하는 가장 일반적인 방법은 표현식 끝에 조건부를 추가하는 것입니다.

new_list = [expression for member in iterable (if conditional)]
로그인 후 복사

여기서 조건문은 오른쪽 대괄호 안에 있습니다.

조건은 목록 내포가 원치 않는 값을 필터링할 수 있도록 허용하기 때문에 중요합니다. 이는 일반적인 경우에 filter()를 호출하여 가능합니다.

numbers = [number for number in range(20) if number % 2 == 0]
print(numbers)
로그인 후 복사

출력:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
로그인 후 복사

보시다시피 이 구문 분석은 다음과 같은 숫자 모음입니다. 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]
로그인 후 복사
로그인 후 복사

Set 표현식

집합 표현식을 만들 수도 있습니다! 기본적으로 목록 이해와 동일합니다. 차이점은 집합 표현식에 중복 항목이 포함되지 않는다는 것입니다. 대괄호 대신 중괄호를 사용하여 집합 표현식을 만들 수 있습니다.

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() 高效得多。

总结

本文向您介绍了列表解析式,以及如何使用它来解决复杂的任务,而不会使您的代码变得过于困难。

现在你:

  • 목록을 만드는 여러 가지 대체 방법을 배웠습니다.
  • 각 방법의 장점을 알아보세요.
  • 루프 및 map() 호출을 단순화하여 이해력을 나열할 수 있습니다.
  • 분석 표현식에 조건부 논리를 추가하는 방법을 이해했습니다.
  • 집합과 사전 표현을 만들 수 있습니다.
  • 분석 표현을 사용하지 말아야 할 때를 배웠습니다.

이 글을 끝까지 읽어주셔서 감사합니다! 이 게시물이 도움이 되셨다면 댓글을 남겨주시고, 제 게시물을 놓치지 않도록 '팔로우'를 꼭 눌러주세요! 당신의 활동은 나의 기쁨입니다! 행운을 빌어요!

위 내용은 Python의 목록 이해가 작업을 해결하는 효율적인 방법입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:51cto.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿