热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python列表元素与转换为元组以进行字符串格式化

我在 codewars 上遇到了一个问题,我不确定这两种可能的解决方案之间有什么区别,一种是将列表转换为元组,另一种是指定输入列表的元素。问题:将姓名(字符串)列表转换为类似于 Facebook 用来

我在 codewars 上遇到了一个问题,我不确定这两种可能的解决方案之间有什么区别,一种是将列表转换为元组,另一种是指定输入列表的元素。

问题:将姓名(字符串)列表转换为类似于 Facebook 用来显示喜欢的语句:“Alex 喜欢这个”、“Alex 和 John 喜欢这个”、“Alex、John 和其他 2 个喜欢这个”等。

使用 if-elif-etc 语句,这非常简单:

if len(names) == 0:
output_string = "no one likes this"
elif len(names) == 1:
output_string = str(names[0]) + " likes this"

但是在较长的姓名列表中,您可以选择:

elif len(names) == 2:
output_string = "%s and %s like this" % (names[0], names[1])

或者

elif len(names) == 3:
output_string = "%s, %s and %s like this" % tuple(names)

我的假设是使用names[0]etc 的计算效率更高,因为您没有在内存中为元组创建新对象 - 是吗?

回答


CPython 优化规则通常基于你推送到 C 层(相对于字节码解释器)的工作量以及字节码指令的复杂程度;对于低级别的绝对工作,解释器的固定开销往往会淹没实际工作,因此从较低级别语言的经​​验中得出的直觉并不适用。

不过,它很容易测试,尤其是使用ipython%timeit魔法(在 WSLv2 下运行的 Alpine Linux 上的 Python 3.8.5 上完成的计时):

In [2]: %%timeit l = [1, 2, 3]
...: tuple(l)
97.6 ns ± 0.303 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [3]: %%timeit l = [1, 2, 3]
...: (l[0], l[1], l[2])
104 ns ± 0.561 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [4]: %%timeit l = [1, 2, 3]
...: (*l,)
78.1 ns ± 0.628 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [5]: %%timeit l = [1, 2]
...: tuple(l)
96 ns ± 0.895 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [6]: %%timeit l = [1, 2]
...: (l[0], l[1])
70.1 ns ± 0.571 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [7]: %%timeit l = [1, 2]
...: (*l,)
73.4 ns ± 0.736 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

因此,实际上,您给出的代码示例为每种尺寸做出了正确的决定(假设性能最重要);在两个元素上,索引比替代方案更快,在三个元素上,转换为tuple批量可以节省足够的重复索引以取胜。

只是为了好玩,我在上面包含了一个等效的解决方案,tuple(l)它使用额外的解包泛化来构建tuple使用专用字节码,它展示了如何用专用优化字节码替换通用构造函数调用这样小的事情可以在固定开销。

这个例子有什么额外的乐趣:更快的(*l,)解决方案实际上涉及两个临时对象;BUILD_TUPLE_UNPACK(实现它的字节码)与BUILD_LIST_UNPACK. 他们俩实际上都构建了一个list,并在最后BUILD_TUPLE_UNPACK将其转换为tuple。所以(*l,)躲在另一个拷贝到临时数据结构,但由于特殊的字节码比这么多有效的内置的查找加通用构造函数的代码路径,它仍然获胜。






推荐阅读
  • 效果预览1基本使用代码voidmain(){启动根目录runApp(MaterialApp(home:TestTipsPage(),));}classTestTipsPageext ... [详细]
  • 在 CentOS 6.4 上安装 QT5 并启动 Qt Creator 时,可能会遇到缺少 GLIBCXX_3.4.15 的问题。这是由于系统中的 libstdc++.so.6 版本过低。本文将详细介绍如何通过更新 GCC 版本来解决这一问题。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • Unity3D平台宏定义之美
    Unity包含一个“平台相关的编译”功能。这包括一些预处理指令,让你分割你的脚本编译和专为支持的平台之一执行代码段。您可以Unity编辑器中运行代码,这 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 本文介绍如何使用线段树解决洛谷 P1531 我讨厌它问题,重点在于单点更新和区间查询最大值。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 基于Linux开源VOIP系统LinPhone[四]
    ****************************************************************************************** ... [详细]
  • 如何在Linux服务器上配置MySQL和Tomcat的开机自动启动
    在Linux服务器上部署Web项目时,通常需要确保MySQL和Tomcat服务能够随系统启动而自动运行。本文将详细介绍如何在Linux环境中配置MySQL和Tomcat的开机自启动,以确保服务的稳定性和可靠性。通过合理的配置,可以有效避免因服务未启动而导致的项目故障。 ... [详细]
  • 优化Vite 1.0至2.0升级过程中遇到的某些代码块过大问题解决方案
    本文详细探讨了在将项目从 Vite 1.0 升级到 2.0 的过程中,如何解决某些代码块过大的问题。通过具体的编码示例,文章提供了全面的解决方案,帮助开发者有效优化打包性能。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • 2022年Python面试题一.Python基础二.企业面试题结束语🥇🥇🥇✅作者简介:大家好我是编程IDὌ ... [详细]
author-avatar
手机用户2602934713
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有