python - python是字符串的运算符行为
问题描述
我无法理解以下行为。我正在创建 2 个字符串,并使用 is 运算符进行比较。在第一种情况下,它的工作方式不同。在第二种情况下,它按预期工作。当我使用逗号或空格时是什么原因,它False
在比较时显示is
,当没有使用逗号或空格或其他字符时,它给出True
Python 3.6.5 (default, Mar 30 2018, 06:41:53)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 'string'
>>> b = a
>>> b is a
True
>>> b = 'string'
>>> b is a
True
>>> a = '1,2,3,4'
>>> b = a
>>> b is a
True
>>> b = '1,2,3,4'
>>> b is a
False
是否有关于为什么 python 以不同方式解释字符串的可靠信息?我最初理解这一点,a
并且b
指的是同一个对象。然后b
得到一个新对象,仍然b is a
说True
。理解这种行为有点令人困惑。
当我使用“字符串”执行此操作时 - 它会产生相同的结果。当我使用 '1,2,3,4' 时出了什么问题 - 它们都是字符串。案例 1 和案例 2 有什么不同?即is
运算符为字符串的不同内容产生不同的结果。
解决方案
关于这种行为的一个重要的事情是,Python 缓存了一些主要是短字符串(通常少于 20 个字符,但不是针对它们的每个组合),以便它们可以快速访问。这样做的一个重要原因是字符串在 Python 的源代码中被广泛使用,并且它是缓存某些特殊类型字符串的内部优化。字典是 Python 源代码中常用的数据结构之一,通常用于保存变量、属性和命名空间,以及其他一些用途,它们都使用字符串作为对象名称。这就是说,每次您尝试访问对象属性或访问变量(本地或全局)时,都会在内部启动字典查找。
现在,出现这种奇怪行为的原因是 Python(CPython 实现)在实习方面对字符串的处理方式不同。在 Python 的源代码中,有一个intern_string_constants函数,它为字符串提供了要被实习的验证,您可以检查以获取更多详细信息。或者查看这篇综合文章http://guilload.com/python-string-interning/。
还值得注意的是,Pythonintern()
在模块中有一个函数sys
,您可以使用它来手动实习字符串。
In [52]: b = sys.intern('a,,')
In [53]: c = sys.intern('a,,')
In [54]: b is c
Out[54]: True
当您想加快字典查找或应该在代码中频繁使用特定字符串对象时,您可以使用此功能。
您不应该与字符串实习混淆的另一点是,当您这样做时a == b
,您正在创建对同一对象的两个引用,这对于那些关键字具有相同的id
.
关于标点符号,似乎如果它们是一个字符,如果它们的长度超过一个,它们就会被拘留。如果长度大于一,它们将不会被缓存。正如评论中提到的,其中一个原因可能是因为关键字和字典键不太可能在其中包含标点符号。
In [28]: a = ','
In [29]: ',' is a
Out[29]: True
In [30]: a = 'abc,'
In [31]: 'abc,' is a
Out[31]: False
In [34]: a = ',,'
In [35]: ',,' is a
Out[35]: False
# Or
In [36]: a = '^'
In [37]: '^' is a
Out[37]: True
In [38]: a = '^%'
In [39]: '^%' is a
Out[39]: False
但是,这些只是您在代码中不能依赖的一些推测。
推荐阅读
- ruby - 厨师 - 将价值从一种资源传递到另一种资源
- javascript - 如何使用来自 url 的登录名和密码来获取请求
- intellij-idea - 我如何 grep Intellij 的构建时间通知 - 哪个日志文件有这些?
- snowflake-cloud-data-platform - 使用 SHOW_INITIAL_ROWS 参数创建的雪花流在选择时引发错误
- r - R:如果条目以字母结尾,则将上面一或两行的信息粘贴到空单元格中
- python - 在 Windows 上: :Go 构建失败并出现错误 ./go-python.h:4:10: fatal error: Python.h: No such file or directory #include "Python.h"
- python - 如何根据id的groupby从先前的测量中创建一个标记(1 - 体重减轻;0 - 相同体重a)体重减轻(8%或更多)的列?
- python - 如何在 Python 中使用带有用户输入和循环的制表模块?
- c# - 画圆点
- xml - xslt 2.0 替换为 xml 结构