8个重构技巧使得Python代码更Pythonic

2023-10-27

1.合并追加到列表声明

我们从一个简单的开始。不是声明一个空列表然后附加到它,而是直接用所有元素初始化列表。这缩短了代码并使意图更加明确。它的性能也稍微好一些,因为它避免了对 append() 的函数调用。

这同样适用于填充其他集合类型,如集合和字典。

2 使用items()直接解包字典值

当遍历字典时,你需要键和值,那么不要手动访问值。而是迭代dictionary.items(),它同时为你提供键和值。

这节省了我们过去分配给 players 的行,代码现在读起来更自然,重复更少。

teams_by_color = {"blue": ["Patrick", "Jessi"]}

for team_color in teams_by_color:
    players = teams_by_color[team_color]
    if is_winning(team_color):
        advance_level(players)

# -> refactor
for team_color, players in teams_by_color.items():
    if is_winning(team_color):
        advance_level(players)

3. 将 range(len) 替换为枚举

如果我们需要遍历列表并且需要同时跟踪索引和当前项,请使用内置enumerate()函数而不是range(len)。这会将当前索引和当前项目作为元组返回。所以我们可以直接在这里查看值,也可以访问带有索引的项目。

for i in range(len(players)):
    print(i, players[i])

# -> refactor
for i, player in enumerate(players):
    print(i, player)

Enumerate 还带有一个可选的start参数。如果你使用它,计数器将从该值开始。但请注意,这些项目仍然从第一个开始。

for i, player in enumerate(players, start=1):
    print(i, player)

4. 用枚举调用替换手动循环计数器

这与之前非常相似。有时我会看到直接对项目执行迭代的代码——这本身并不坏——但随后需要一个计数器,它会在循环内手动递增。同样在这里你可以简单地使用 enumerate 函数。这更简单,也更快。

i = 0
for player in players:
    print(i, player)
    i += 1

# -> refactor
for i, player in enumerate(players):
    print(i, player)

4.1 不要手动更新计数器

如果你只需要计算项目的数量,也不要遍历循环并手动计算所有项目。相反,只需使用len()函数来获取列表中的元素数。

num_players = 0
for player in players:
    num_players += 1

# -> refactor
num_players = len(players)

5.将条件简化为return语句

当我们到达一个方法的末尾并想要返回 True 或 False 时,一种常见的做法是这样的。如果条件为 True,我们返回 True。否则我们最后返回 False。然而,直接返回结果更简洁:

def function():
    if isinstance(a, b) or issubclass(b, a):
        return True
    return False

# -> refactor
def function():
    return isinstance(a, b) or issubclass(b, a)

我们在这里应该注意的一件事是,只有当表达式的计算结果为布尔值时才能这样做。isinstance()issubclass()都是返回布尔值的函数,所以这很好。但在下一个示例中,第一个表达式pythonistas是一个列表而不是布尔值。

如果pythonistas是一个有效的非空列表,这将返回列表而不是预期的布尔值,然后可能是你的应用程序中的错误。因此,为了确保我们在这里返回一个布尔值,我们可以将返回包装在对 bool()函数的调用中。

def any_pythonistas():
    pythonistas = [coder for coder in coders if is_good_in_python(coder)]
    if pythonistas or self.is_pythonista():
        return True
    return False

# -> refactor
def any_hats():
    pythonistas = [coder for coder in coders if is_good_in_python(coder)]
    return bool(pythonistas or self.is_pythonista())

6.合并条件中的重复块

我们应该始终寻找机会删除重复的代码。这样做的好地方是if …elif链中有多个相同的块。

在此示例中,if 和 elif 都导致相同的执行功能。所以我们可以使用or组合前两个块来删除对函数的重复调用。现在,如果我们需要更改process_standard_payment()行,我们可以在一处而不是两处进行。

def process_payment(payment, currency):
    if currency == "USD":
        process_standard_payment(payment)
    elif currency == "EUR":
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

# -> refactor
def process_payment(payment, currency):
    if currency == "USD" or currency == "EUR":
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

7.用in运算符替换同一个变量的多次比较

我们甚至可以进一步重构以前的代码。由于我们针对多个值重复检查同一个变量,我们可以使用 in 运算符来缩短它。如果货币值在定义的列表中,我们将执行专用操作。

def process_payment(payment, currency):
    if currency == "USD" or currency == "EUR":
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

# -> refactor
def process_payment(payment, currency):
    if currency in ["USD", "EUR"]:
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

为了再次改进这一点,我们应该在这里使用一个集合。在集合中查找值更快,而且无论如何我们都想要这里的唯一元素,所以集合是更好的选择。

# -> refactor
def process_payment(payment, currency):
    if currency in {"USD", "EUR"}:
        process_standard_payment(payment)
    else:
        process_international_payment(payment)

8. 将 for 循环中的 yield 替换为 yield from

如果你已经熟悉生成器,那么这是一个高级技巧。一个经常被忽略的小技巧是 Python 的 yield 关键字对于可迭代对象有一个对应的yield from

如果你有一个像列表这样的可迭代对象,而不是说for item in iterable: yield item,你可以简单地说yield from iterable。这更短,并且消除了对可迭代对象的手动循环,这也可以提高性能。

def get_content(entry):
    for block in entry.get_blocks():
        yield block

# -> refactor
def get_content(entry):
    yield from entry.get_blocks()

players = []
players.append("Patrick")
players.append("Max")
players.append("Jessi")

# -> refactor
players = ["Patrick", "Max", "Jessi"]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

8个重构技巧使得Python代码更Pythonic 的相关文章

  • goJS 下拉菜单删除项目

    我有简单的 python Flask goJS 图形应用程序 如下所示 节点和链接文本的源是从应用程序的后端加载的 我将它们设置为model modelData像这样的部分 var graphDataString JSON parse di
  • 在Linux中的端口80上运行flask[重复]

    这个问题在这里已经有答案了 也许以前有过这个问题的答案 所以请重定向我 如果是这样的话 我正在考虑在端口 80 上运行 Flask 所以我检查了是否有任何东西正在使用端口 80 因为事实证明端口 80 没有运行 所以当我输入以下内容时 if
  • 如何在Python中找到低精度浮点值的原始文本表示?

    我遇到了显示问题floatPython 中的值 从外部数据源加载 它们是 32 位浮点数 但这也适用于较低精度的浮点数 以防万一 这些值是由人类在 C C 中输入的 因此与任意计算值不同 与round数字很 可能not预期的 但不能被忽略
  • python类型中的__flags__有什么用

    我最近阅读了pickle源代码 以下代码在copy reg让我很困惑 HEAPTYPE 1 lt lt 9 def reduce ex self proto assert proto lt 2 for base in self class
  • 如何从数据库模式自动生成示例 Django 应用程序?

    我正在评估概念验证应用程序的框架 该应用程序的生命周期约为 30 天 之后它将被遗忘或完全重写 我已确定要从现有数据库模式自动生成示例应用程序 然后调整视觉设计的某些方面 我看过一个演示红宝石 on Rails 它会为数据库中的每个表自动生
  • matplotlib 的 pcolor 中的白线

    在某些 pdf 查看器 例如 OSX 上的 Preview 中 使用以下命令绘制的图matplotlib的 pcolor 有白线 见下图 我怎样才能摆脱它们 源代码非常简单 选择任何数据x y z import matplotlib mat
  • gcloud app deploy:此部署有太多文件

    当我尝试通过 gcloud 部署我的 GAE 应用程序时 出现以下错误 Updating service default failed ERROR gcloud app deploy Error Response 400 This depl
  • 如何逐行替换(更新)文件中的文本

    我试图通过读取每一行 测试它 然后写入是否需要更新来替换文本文件中的文本 我不想保存为新文件 因为我的脚本已经先备份文件并对备份进行操作 这是我到目前为止所拥有的 我从 os walk 获取路径 并且保证 pathmatch var 正确返
  • Python中非常大的整数的math.pow是错误的[重复]

    这个问题在这里已经有答案了 我试图通过计算一个整数的非常大的幂来打印一个非常大的数字 尽管我的代码是正确的 但我没有观察到所需的输出 一般来说 Python解释器可以打印系统内存支持的非常大的整数 考虑到这个假设 下面是我正在运行的代码 a
  • PRAW 出现 SSLError?

    我正在尝试开始使用 PRAW 但在使用 login 时遇到问题 我有以下代码 import praw r praw Reddit This is a test bot r login myRedditUsername password 我收
  • Python/Scipy 2D 插值(非均匀数据)

    这是我上一篇文章的后续问题 Python Scipy 插值 地图坐标 https stackoverflow com questions 5124126 python scipy interpolation map coordinates
  • 如何在Python中重命名virtualenv?

    我拼错了名字virtualenv使用以下方法初始化它 virtualenv vnev 我实际上打算创建一个名为的环境venv 尝试重命名后vnev文件夹到venv 我发现这并没有提供太多帮助 激活环境的名称仍然重命名旧的vnev mv vn
  • Kivy错误(python 2.7):sdl2导入错误

    我尝试在我的 Python 2 7 项目 在 PyCharm Windows 10 环境中 上使用 kivy 但出现以下错误 如果有人可以帮助我吗 谢谢 PS 我多次尝试卸载 重新安装库等 并按照像这样的帖子上的建议进行操作 但它不起作用
  • 更改 Windows 上的 virtualenv 文件夹

    计算机修复后 我的 python 项目目录 Windows 发生了变化 比如从 d 到 f 现在我所有的 virtualenv 都坏了 激活 env 后 virtualenv 中的项目无法找到依赖项 并且自定义脚本 来自 env scrip
  • Python 多处理:全局对象未正确复制到子级

    前几天我回答了一个关于SO的问题 https stackoverflow com q 67047533 1925388关于并行读取 tar 文件 这是问题的要点 import bz2 import tarfile from multipro
  • Python 柯里化任意数量的变量

    我正在尝试使用柯里化在 Python 中进行简单的函数添加 我找到了这个咖喱装饰器here https gist github com JulienPalard 021f1c7332507d6a494b def curry func def
  • 为什么变量不在循环外更新?

    无法弄清楚为什么结果中的第一个键是 abc 而不是我期望的 c 我使用的是Python 3 6 4 数据结构很奇怪 因为我删除了不相关的键和值 f replace ab r data abc 1 def 2 ghi 3 jkf 4 lmn
  • 无法从源 pylance 解析导入烧瓶

    我正在学习 Python 课程的一部分是使用 Flask 设置网络服务器 我按照 Flask 安装文档执行了步骤 由于某种原因 flask 模块带有下划线 如下所示 当我将鼠标悬停时 我会得到如下附加信息 无法从源 pylance 解析导入
  • 如何找到 JAR:/home/hadoop/contrib/streaming/hadoop-streaming.jar

    我正在练习有关 Amazon EMR 的复数视角视频教程 我被困住了 因为我收到此错误而无法继续 Not a valid JAR home hadoop contrib streaming hadoop streaming jar 请注意
  • 如何从集合中检索元素而不删除它?

    假设如下 gt gt gt s set 1 2 3 我如何获得一个值 任何值 s不做s pop 我想将该项目保留在集合中 直到我确定可以删除它 这只有在异步调用另一个主机之后才能确定 又快又脏 gt gt gt elem s pop gt

随机推荐

  • 【MySQL】免安装版MySQL安装教程

    前言 近日 重新安装了一下本地的数据库 参考了很多博客才将MySQL给安装好 为了方便以后安装 便结合了网上博客的安装方法以及自己的一些经验写下这篇博客 也希望能给你们带来帮助 一 MySQL是什么 MySQL 是一个关系型数据库管理系统
  • docker配置seata分布式事务并注册至nacos

    Docker配置分布式事务Seata并注册到Nacos服务中心 Docker常用基础命令 docker ps 查询当前服务器的服务 docker images 查看服务下载的镜像 docker ps a 查看所有的服务 包含未开启的服务 d
  • 【Protobuf(四)】消息格式

    protobuf是一种平台语言无关的消息序列化协议 相比于传统的json xml 序列后的空间更小 但是无法自解释 需要结合额外的proto定义文件才能反序列化 当然这样也更安全 下面记录一下protobuf消息格式 protobuf消息序
  • 统计与分布之伯努利分布与二项分布

    目录 目录 前文列表 伯努利分布 二项分布 前文列表 计数原理 组合与排列 统计与分布之高斯分布 统计与分布之泊松分布 伯努利分布 伯努利分布 Bernoulli Distribution 是一种离散分布 又称为 0 1 分布 或 两点分布
  • 测试用例编写

    今天主要编写了办公模块下快速创建板块中的测试用例 快速创建提日志 多个功能点钟含有相同的功能 而且功能以模块的形式呈现 包含的功能较多 可以把该模块提取出来单独编写测试用例 这样就不用再每个功能点下重复编写 在快速创建日志中 日报 周报 月
  • The kdb Kernel Debugger

    The kdb Kernel Debugger Many readers may be wondering why the kernel does not have any more advanced debugging features
  • leetcode:62. 不同路径

    题目来源 leetcode 题目描述 题目解析 从暴力搜索到动态规划 暴力搜索 class Solution 机器人从 i j 走到 m n 一共有几种方法 int process int i int j int m int n if i
  • ASP + SQL Server聊天室设计实例

    ASP SQL Server聊天室设计实例 目 录 第一章 绪论 1 1 设计思想 1 2 开发工具和相关技术简介 第二章 聊天室总体分析和设计 2 1 聊天室的运行原理 2 2 聊天室的功能 2 3 聊天室的页面结构设计 2 4 聊天室的
  • hive之full outer join(全连接)使用方法

    目录 介绍 语法 例子 创建顾客表 customers 创建订单表 orders full outer join语句 left join union right join语句 介绍 full outer join结合了 LEFT JOIN
  • vue 指定元素滚动到页面可视区域

    使用场景 1 点击页面tab 或步骤条的某一步 使其对应元素滚动到页面可视区域 2 使遍历而来的list滚动到页面可视区域 实现 使用el scrollIntoView API实现 scrollIntoView 方法会滚动元素的父容器 使被
  • db2 replace函数的用法_高效的10个Pandas函数,你都用过吗?

    作者 Soner Y ld r m 来源 towardsdatascience 翻译 编辑 Python大数据分析 Pandas是python中最主要的数据分析库之一 它提供了非常多的函数 方法 可以高效地处理并分析数据 让pandas如此
  • 类模板 构造函数_C++ 类模板(学习笔记:第9章 02)

    类模板 1 类模板的作用 使用类模板使用户可以为类声明一种模式 使得类中的某些数据成员 某些成员函数的参数 某些成员函数的返回值 能取任意类型 包括基本类型的和用户自定义类型 类模板的声明 类模板 template lt 模板参数表 gt
  • oracle 查询随机数据结构,批量随机键值查询测试

    摘要 当数据量巨大时 使用大批量随机键值集获取对应记录集合 不仅仅考验数据库软件本身 更在于程序员对数据的理解 如何在硬件资源有限的情况下将性能发挥到极致 点击 批量随机键值查询测试 来乾学院一探究竟 本次测试主要针对集算器组表索引实现的批
  • 15个 Android 通用流行框架

    转载自 http www techug com 15 android framework biz MjM5OTA1MDUyMA mid 407358558 idx 2 sn b21877f23bf4063fa311185009c1f0b7
  • PLSQL显示优化

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 首选项 Tools gt Preferences 1 字体大小调整 高分屏看的清 2 设置关键字自动大写 3 设置关键字颜色 实现效果 转载于 https my oschi
  • kdj超卖_KDJ买卖口诀:“J值大于100逐步卖,J值接近负值逐步买”,从贫穷到富有原来如此简单...

    KDJ指标又叫随机指标 是一种相当新颖 实用的技术分析指标 指标构成 K线是快速确认线 数值在90以上就是超买 数值在10以下就是超卖 D线是慢速主干线 数值在80以上就是超买 数值在20一下就是超卖 J线是方向敏感线 当J值大于100 特
  • 编程小记—— C/C++中 x & -x 表示含义

    说明 看多了各种优秀看源代码的经常会遇到一些很常见的公式 本篇文章记录的 x x 就是其中的一种 含义 我们都知道 x 的值 其实就是在x的值的基础上进行按位取反 x 之后在增加1所得 也就是说 x x x x 1 x 为偶数 我们都知道
  • web信息收集

    title 信息收集 tags null categories 信息收集 null date 2021 03 20 18 40 54 keywords top img cover updated sticky description cop
  • 用 request请求对象 获取请求头里的 信息

    1 根据请求头名称获取一个值 String connection request getHeader connection System out println connection System out println getHeader
  • 8个重构技巧使得Python代码更Pythonic

    1 合并追加到列表声明 我们从一个简单的开始 不是声明一个空列表然后附加到它 而是直接用所有元素初始化列表 这缩短了代码并使意图更加明确 它的性能也稍微好一些 因为它避免了对 append 的函数调用 这同样适用于填充其他集合类型 如集合和