Python的eval()和int()的几点区别和性能差异

博主刷数的运算题时发现两段相似代码运行时间差异大,经分析是因一个API函数影响效率。对比了eval()与int()函数,int()在整数转换上更优,eval()执行表达式有安全风险,还介绍了二者在处理不同类型数据时的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


tags: Python Tips

写在前面

今天刷几道关于数的运算的题, 我发现了一个很匪夷所思的问题:

两段几乎完全一样的代码, 其运行时间差异怎么会如此之大呢?(题目:415. 字符串相加 - 力扣(LeetCode))

# 我的代码
class Solution:
    def addStrings(self, num1: str, num2: str) -> str:
        na,nb=len(num1)-1,len(num2)-1
        add=0
        ans=''
        while na>=0 or nb>=0 or add:
            a=eval(num1[na]) if na>=0 else 0
            b=eval(num2[nb]) if nb>=0 else 0
            tmp=a+b+add
            ans+=str(tmp%10)
            add=tmp//10
            na-=1
            nb-=1
        return ans[::-1]

下面是官方代码:

class Solution:
    def addStrings(self, num1: str, num2: str) -> str:
        na,nb=len(num1)-1,len(num2)-1
        add=0
        ans=''
        while na>=0 or nb>=0:
            a=int(num1[na]) if na>=0 else 0
            b=int(num2[nb]) if nb>=0 else 0
            tmp=a+b+add
            ans=str(tmp%10)+ans
            add=tmp//10
            na-=1
            nb-=1
        return '1'+ans if add else ans

乍一看没什么问题, 但是我的代码就是188ms, 而官方的是36ms, 这就很奇怪了…

分析

后来一番对比发现, 真正的罪魁祸首并不在代码逻辑方面, 而在于一个小小的API函数eval(), 这个函数虽然也能将字符串转换为整数, 但是其效率非常低…

其实从力扣的判题就能看出来了, 但是我还是想在本地试试:

from time import time 
st=time()
ans=[]
for i in range(10000000):
    ans.append(eval(str(i)))
print("ok")
print("time :", time()-st)

上面的代码运行时间为:34.3s, 而将eval换成int之后程序运行时间只有3.6s, 足可见其对运行效率的影响.

那么, 到底是什么原因导致差异的呢?

eval()与int()比较

这里参考了一些stack的回答1.

  1. int()函数只能对仅含有整数的字符串做处理, 而并不进行字符串的检查, 当然, 这里一个额外的情况如下:

    In [1]: int('01')
    Out[1]: 1
    
    In [2]: eval('01')
      File <string>:1
        01
         ^
    SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
    
    

    可以看到前导零并不会影响int, 但是eval会首先将前导零认为是八进制数字, 这也是int()eval()在整数转换时候不一样的地方(int更胜一筹);

  2. 对于浮点数, 只能使用eval(), 看下面的例子:

    In [3]: int('1.1')
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    Input In [3], in <cell line: 1>()
    ----> 1 int('1.1')
    
    ValueError: invalid literal for int() with base 10: '1.1'
    
    In [4]: eval('1.1')
    Out[4]: 1.1
    
  3. 在与eval()搭配使用input()的时候需要注意, 由于eval()会执行Python中的表达式, 那就会有下面的一个问题.

    一般的Python入门书中对于用户输入都是这样写的:

    x=eval(input("Enter a number:"))
    

    这样当然可以得到一个完整的数字, 但是也有一定的安全风险, 这里的安全风险指的是: 在并没有输入类型检查的情况下, 如果用户输入了一段代码, 那么这段代码将会被eval函数执行. 看下面的例子:

    x=eval(input("Enter a number:"))
    # 此时输入下面的内容
    __import__('os').system("rm -rf *")
    

    如果你使用的是类Unix系统, 并且此时工作目录下有一些源文件, 那么当你使用了这个程序的时候, 此时目录中的内容就消失了(谨慎操作).

ref


  1. python - “eval”和“int”有什么区别 - Stack Overflow; ↩︎

<think>好的,用户让我介绍一下Python 3.6Python 2.6之间的区别,需要详细说明。首先,我需要回忆这两个版本的主要变化,特别是考虑到2.6到3.6之间的跨度比较大,中间有很多重要的变化。不过用户可能更关注这两个特定版本之间的差异,而不仅仅是Python 23的一般区别。 首先,Python 2.6是在2008年发布的,而Python 3.6则在2016年发布。这两个版本之间相隔了8年,所以会有很多重大变化。用户可能想知道从2.6升级到3.6需要注意哪些方面,或者为什么需要迁移。 接下来,我需要从几个方面来比较这两个版本。首先是语法差异Python 3引入了很多不兼容的语法变化,比如print从语句变成函数,这应该是基本点。还有除法运算符的变化,在Python 3中,3/2会得到1.5,而Python 2中则是1。另外,Unicode处理的不同,Python 3的字符串默认是Unicode,而Python 2则有strunicode两种类型。还有xrange在Python 3中被移除,range代替了它,所以循环结构可能也有变化。异常处理的语法,比如as关键字的使用,以及raise语句的改进。这些都属于语法层面的不同。 然后是标准库的变化。Python 3中很多模块被重命名或重组,比如urllib、Tkinter等。还有新的模块加入,比如在3.4引入的asyncio,但可能在3.6中有所增强。此外,一些旧的模块被弃用或删除,比如在Python 2.6中可能还在使用的模块,在3.6中可能已经不存在了。 接下来是性能改进。Python 3.6相比2.6在性能上应该有不少优化,比如字典的实现更高效,启动时间更快,或者内存使用的改进。此外,可能还有新的特性比如异步编程的支持,通过asyncawait关键字,这在处理并发时很有用。 还有新特性方面,Python 3.6引入了格式化字符串字面量(f-strings),这使得字符串格式化更简洁。变量类型注释,这对于代码的可读性静态类型检查有帮助。还有字典保持插入顺序的特性,虽然这是CPython的实现细节,但在3.7成为正式规范。此外,模块的改进,比如secrets模块用于安全相关的随机数生成,pathlib的增强等。 兼容性迁移工具也是需要考虑的方面。Python 2.6到3.6的迁移可能需要使用2to3工具,或者像six这样的兼容库。用户可能需要知道迁移过程中可能遇到的常见问题,比如如何处理旧代码中的print语句,Unicode字节串的处理,以及标准库模块的变化。 另外,需要指出的是Python 2.6已经非常老旧,官方支持早已结束,而Python 3.6虽然也不是最新的,但相对于2.6来说更现代,用户可能应该升级到更高版本的3.x,比如3.7或3.8,尤其是考虑到安全性新功能。 在组织内容时,应该分点说明,比如分成语法变化、标准库、新特性、性能、兼容性等部分。每个部分下再列举具体的不同点,并给出示例,比如print的不同用法,除法结果,字符串类型差异等。这样用户更容易理解。 还要注意用户可能的实际需求,比如他们可能正在维护旧的Python 2.6代码,想要迁移到3.6,所以需要知道哪些地方需要修改,常见问题是什么。或者他们可能是在学习Python,想了解版本之间的差异,避免混淆。 最后,总结时强调迁移的必要性,以及升级到更高版本Python 3的好处,比如更好的性能、更多现代特性、社区支持等。可能还要提到Python 2已经停止维护,存在安全风险,因此迁移是必要的。</think>Python 3.6 Python 2.6 是两个差异巨大的版本,涵盖了语法、标准库、性能优化编程范式等多方面的改进。以下是两者的主要区别,按类别详细说明: --- ### **一、核心语法差异** 1. **`print` 语句 vs 函数** - **Python 2.6**: `print` 是语句,如 `print "Hello"`。 - **Python 3.6**: `print()` 是函数,必须加括号:`print("Hello")`。 2. **整数除法行为** - **Python 2.6**: `3 / 2` 返回 `1`(整除),`3.0 / 2` 返回 `1.5`。 - **Python 3.6**: `3 / 2` 始终返回 `1.5`,整除需用 `//` 运算符。 3. **Unicode 支持** - **Python 2.6**: 字符串默认是字节串(`str`),需前缀 `u` 定义 Unicode(如 `u"中文"`)。 - **Python 3.6**: 字符串默认是 Unicode(`str`),字节串需前缀 `b`(如 `b"bytes"`)。 4. **`xrange` 的移除** - **Python 2.6**: `range` 返回列表,`xrange` 返回生成器以节省内存。 - **Python 3.6**: `range` 实现类似 `xrange` 的行为,`xrange` 被移除。 5. **异常处理语法** - **Python 2.6**: `except Exception, e:`。 - **Python 3.6**: 必须用 `as` 关键字:`except Exception as e:`。 --- ### **二、标准库变化** 1. **模块重命名** - `urllib2`、`urlparse`(Python 2) → 合并为 `urllib`(Python 3)。 - `Tkinter` → `tkinter`(小写)。 - `Queue` → `queue`。 2. **新增模块** - **`asyncio`**:异步 I/O 支持(Python 3.4+)。 - **`pathlib`**:面向对象的路径操作(Python 3.4+)。 - **`secrets`**:安全随机数生成(Python 3.6+)。 3. **弃用模块** - `commands`、`md5` 等模块被移除,推荐使用 `subprocess` 或 `hashlib`。 --- ### **三、新特性与功能** 1. **格式化字符串(f-strings)** Python 3.6 引入 `f"Hello {name}"`,允许直接嵌入变量表达式。 2. **类型注解** Python 3.6 支持变量类型注释(需配合 `mypy` 等工具): ```python name: str = "Alice" def add(a: int, b: int) -> int: ... ``` 3. **字典保持插入顺序** Python 3.6 中字典默认保留插入顺序(Python 3.7 正式成为语言规范)。 4. **异步编程支持** Python 3.5+ 引入 `async`/`await` 关键字,3.6 优化了异步生成器推导式。 -- ### **四、性能优化** 1. **字典实现优化** Python 3.6 采用更紧凑的字典结构,内存占用减少 20%-25%。 2. **启动时间优化** Python 3 的模块导入机制更快,启动速度显著提升。 3. **内存管理** 改进的垃圾回收机制,减少循环引用的内存泄漏问题。 --- ### **五、向后不兼容变化** 1. **`input()` 函数行为** - Python 2.6 的 `input()` 等效于 `eval(raw_input())`。 - Python 3.6 的 `input()` 直接返回字符串(同 Python 2 的 `raw_input()`)。 2. **迭代器替代列表** Python 3 中 `map()`、`filter()`、`zip()` 返回迭代器而非列表,需用 `list()` 转换。 --- ### **六、迁移与兼容性** 1. **迁移工具** - 使用 `2to3` 自动转换 Python 2 代码到 Python 3。 - `six` 库可编写兼容两个版本的代码。 2. **兼容性问题** - 所有字符串字节操作需显式处理编码(如 `str.encode()` `bytes.decode()`)。 - 第三方库需确保支持 Python 3。 --- ### **七、总结与建议** - **Python 2.6 已停止支持**(官方维护截止于 2013 年),存在安全风险。 - **Python 3.6+ 是现代化选择**,拥有更高效的语法、性能功能。 - 建议直接迁移到 **Python 3.10+**(截至 2023 年最新稳定版),以获取更多新特性(如模式匹配、类型系统增强等)。 如果需要进一步了解具体迁移步骤或代码示例,可以补充说明!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zorchp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值