在Python中使用列表推导式List Comprehension的8个层次

2023-12-29 15:04

本文主要是介绍在Python中使用列表推导式List Comprehension的8个层次,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在Python中使用列表推导式的8 个层次(8 Levels of Using List Comprehension in Python)

文章目录

  • 在Python中使用列表推导式的8 个层次(8 Levels of Using List Comprehension in Python)
    • Level 0: 了解列表推导式List Comprehension的模板Template
    • Level 1: 只需替换 For 循环
    • Level 2: 巧妙使用 If 条件Condition
    • Level 3: 使用更复杂的表达式More Complex Expression
    • Level 4: 使用嵌套For循环处理嵌套Iterables
    • Level 5: 避免使用高阶函数Higher Order Functions以提高可读性Readability
    • Level 6: 使用生成器表达式Generator Expressions降低内存开销Reduce Memory Costs
    • Level 7: 了解列表推导式List Comprehension背后的哲学Philosophy
    • 结论

列表表达式 list comprehension是一种非常具有 Pythonic 风格的技术,能让你的代码变得非常优雅。不过,它的语法有点令人困惑,尤其是对于新手和来自其他语言的程序员来说。我读过很多关于它的资料,但说实话,没有一本能完美地展示列表理解的全貌,以及它有多么强大和美丽。因此,我写了这篇文章。

本篇文章将由浅入深elementary to profound地展示使用列表表达式list comprehension的 8 个层次。在了解了所有 8 个层次之后,掌握列表表达式list comprehension就变得易如反掌了。

在Python中,“List comprehension”是指一种简洁的语法结构,用于快速创建新的列表,同时对列表中的元素进行处理和筛选。因此,我们可以将“List comprehension”理解为“列表理解”或“列表推导式”或“列表表达式”,即通过理解和推导原始列表中的元素,生成一个新的列表。

Level 0: 了解列表推导式List Comprehension的模板Template

首先,我们应该了解基本语法:

每个列表推导式List Comprehension都应遵守以下模板:

my_list = [ expression for item in iterable (if condition) ]

它非常简洁明了。只有两个方括号square brackets,包括三个关键组件components:

  • 迭代iterate可迭代对象iterable的 for 循环
  • 处理项item的表达式expression
  • 一个可选的 if 条件condition

接下来,让我们看看如何利用这个简单的模板编写巧妙的程序。

Level 1: 只需替换 For 循环

一个直观的方案是用一行代码替换 for 循环:

full_name = "Zhang San"
characters = [char for char in full_name]
print(full_name)
print(characters)
# Zhang San
# ['Z', 'h', 'a', 'n', 'g', ' ', 'S', 'a', 'n']

与下面的 for 循环版本实现相比,这已经是向 Pythonic 和优雅程序迈进了一大步。

full_name = "Zhang San"
characters = []
for char in full_name:characters.append(char)
print(full_name)
print(characters)
# Zhang San
# ['Z', 'h', 'a', 'n', 'g', ' ', 'S', 'a', 'n']

实际上,Python 中的所有可迭代对象iterables都可以在列表推导式List Comprehension中使用。再举一个例子

Matrix = [[2, 1, 5],[5, 99, 0],[33, 2, 4]]
row_max = [max(row) for row in Matrix]
print(row_max)
# [5, 99, 33]

如上例所示,我们只需一行代码就能得到矩阵matrix中每一行的最大值maximum value。

Level 2: 巧妙使用 If 条件Condition

if 语句statement是列表推导式List Comprehension中的一个可选条件optional condition。如果使用得当,它会给我们带来很多方便。

Genius = ["Yang", "Tom", "Jerry", "Jack", "tom", "yang"]
L1 = [name for name in Genius if name.startswith('Y')]
L2 = [name for name in Genius if name.startswith('Y') or len(name) < 4]
L3 = [name for name in Genius if len(name) < 4 and name.islower()]
print(L1, L2, L3)
# ['Yang'] ['Yang', 'Tom', 'tom'] ['tom']

Level 3: 使用更复杂的表达式More Complex Expression

在前面的示例中,我们只是获取项items来建立列表list。实际上,我们可以对 items 使用更复杂的表达式:

Genius = ["Jerry", "Jack", "tom", "yang"]
L1 = [name.capitalize() for name in Genius]
print(L1)
# ['Jerry', 'Jack', 'Tom', 'Yang']

甚至包括 if...else... 语句:

Genius = ["Jerry", "Jack", "tom", "yang"]
L1 = [name if name.startswith('y') else 'Not Genius' for name in Genius]
print(L1)
# ['Not Genius', 'Not Genius', 'Not Genius', 'yang']

注意:如果您没有真正理解列表推导式List Comprehension的模板Template,有一个问题可能会让您感到困惑:

表达式中的 if...else... 语句(也称为三元条件操作符ternary conditional operator)与列表推导式List Comprehension模板Template最后的可选 if 条件不同。让我们回顾一下模板:

my_list = [ expression for item in iterable (if condition) ]

如模板所示,最后一个 if 条件是列表推导式List Comprehension的组成部分之一。我们不能在它后面添加 else 语句,因为列表推导式List Comprehension的语法不支持这样做。

只要遵循 Python 表达式的语法,表达式部分可以是任何表达式。如果我们使用 if ,则必须同时使用 else ,因为这是 Python 表达式的三元条件运算符ternary conditional operator语法。

a = 1
b = 2 if a>0 # SyntaxError: invalid syntaxb = 2 if a > 0 else -1  
# b==2,ternary conditional operator works

Level 4: 使用嵌套For循环处理嵌套Iterables

一个列表推导式List Comprehension不仅可以替代一个 for-loop,实际上还可以替代嵌套的 for-loop。

Genius = ["Jerry", "Jack", "tom", "yang"]
L1 = [char for name in Genius for char in name]
print(L1)
# ['J', 'e', 'r', 'r', 'y', 'J', 'a', 'c', 'k', 't', 'o', 'm', 'y', 'a', 'n', 'g']

上述程序等于

Genius = ["Jerry", "Jack", "tom", "yang"]
L1 = []
for name in Genius:for char in name:L1.append(char)
print(L1)

哪种实现方式更好?答案显而易见。

当然,我们可以在一个列表推导式List Comprehension中放入更多嵌套的 for 循环,但这不是一个好主意。出于可读性的考虑,最好的做法best practice是在一个列表推导式List Comprehension中不要使用超过两个 for 循环。

此外,我们还可以在任何 for 循环之后添加可选的 if 条件conditions:

Genius = ["Jerry", "Jack", "tom", "yang"]
L1 = [char for name in Genius if len(name) < 4 for char in name]
print(L1)
# ['t', 'o', 'm']

Level 5: 避免使用高阶函数Higher Order Functions以提高可读性Readability

Python 有一些高阶函数higher order functions,如 map()filter() 等。一个好的习惯是尽量使用列表推导式List Comprehension而不是使用高阶函数。因为它能让我们的程序更容易被他人阅读。甚至 Python 的作者也在他的文章中推荐了这种做法。

map() 方法可以使用列表推导式List Comprehension进行替换:

L = map(func, iterable)
# can be replaced to:
L = [func(a) for a in iterable]

filter() 方法也可以使用列表推导式List Comprehension进行转换:

L = filter(condition_func, iterable)
# can be converted to
L = [a for a in iterable if condition]

让我们来看一个例子,下面的列表( L1L2 )用两种不同的方法实现,结果是一样的:

Genius = ["Jerry", "Jack", "tom", "yang"]
L1 = filter(lambda a: len(a) < 4, Genius)
print(list(L1))
# ['tom']
L2 = [a for a in Genius if len(a) < 4]
print(L2)
# ['tom']

Level 6: 使用生成器表达式Generator Expressions降低内存开销Reduce Memory Costs

如果我们将方括号square brackets转换成括号parentheses,列表推导式List Comprehension就会变成一个生成器表达式generator expression。

生成器表达式generator expression可以避免生成一个完整的列表full list,从而降低内存成本reduce memory costs,因为生成器generator采用了 惰性求值lazy evaluation。

large_list = [x for x in range(1_000_000)]
large_list_g = (x for x in range(1_000_000))
print(large_list.__sizeof__())
print(large_list_g.__sizeof__())
# 8697440
# 96

在Python中,__sizeof__()是一个特殊方法,用于返回对象所占用的内存大小(单位为字节)。它可以用于任何Python对象,包括列表、元组、字典、集合、自定义对象等。

Level 7: 了解列表推导式List Comprehension背后的哲学Philosophy

使用列表推导式List Comprehension的直观原因是为了使我们的代码更加整洁和优雅neat and elegant。此外Furthermore,这也是函数式编程范式functional programming paradigm的良好实践practice。函数式编程的理念之一就是避免控制流avoiding control flows。列表推导式List Comprehension可以将程序员的注意力从控制流control flow转移到数据收集data collection本身。换句话说,从思考 for 循环如何工作到思考列表是什么,这是一种心理上的转变。it’s a mentally shift from thinking of how a for-loop works to what the list is. 它可以帮助你更容易地思考整个程序的逻辑。

结论

列表推导式List Comprehension是展示 Python 程序如何优雅elegant的经典示例classic example。在熟悉了它的语法syntax和使用场景using scenarios后,你的 Python 编程技能programming skills将进入一个新的境界new realm。

这篇关于在Python中使用列表推导式List Comprehension的8个层次的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/549800

相关文章

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑