这里的读者大部分都是因为 Python 来关注我的,今天我就再分享一些关于 Python 语言的有趣现象,帮助你更深入地理解和使用 Python。
字符串
先看几行代码
1、
>>> a = "some_string"
>>> id(a)
140420665652016
>>> id("some" + "_" + "string") # 注意两个的id值是相同的.
140420665652016
2、
>>> a = "wtf"
>>> b = "wtf"
>>> a is b
True
>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False
>>> a, b = "wtf!", "wtf!"
>>> a is b
True
3、
>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False
很好理解,对吧?
这里我在唠叨下:
-
id 是取一个对象在内存中的地址,id 一样,就是同一个对象。A 和 B 的 id 一样,那么 A is B 就是 True,否则就是 False。
-
编译器(CPython)在编译优化时,某些情况下会尝试使用已经存在的不可变对象,而不是新创建一个新对象,这样可以节省内存。这种行为叫字符串的驻留。(到这里可以解释1)
-
字符串中只包含字母、数字或下划线时将会驻留,所以 ‘wtf!' 由于包叹号,所以不被驻留,当在同一行将 a 和 b 的值设置为 "wtf!" 的时候, Python 解释器会创建一个新对象, 然后同时引用第二个变量. 如果你在不同的行上进行赋值操作, 它就不会“知道”已经有一个 wtf! 对象,它是一种编译器优化, 特别适用于交互式环境。(到这里你已经明白2的结果了)
-
常量折叠是 Python 中的一种 窥孔优化(peephole optimization) 技术。这意味着在编译时表达式 'a'*20 会被替换为 'aaaaaaaaaaaaaaaaaaaa' 以减少运行时的时钟周期。只有长度小于 20 的字符串才会发生常量折叠。(到这里已经明白3的结果了)
字典
先看几行代码
>>> some_dict = {}
>>> some_dict[1.1] = "Ruby"
>>> some_dict[1.0] = "JavaScript"
>>> some_dict[1] = "Python"
>>> some_dict[1.1]
'Ruby'
>>> some_dict[1.0]
'Python'
>>> some_dict[1]
'Python'
>>>
-
Python 字典通过检查键值是否相等和比较哈希值来确定两个键是否相同。
-
具有相同值的不可变对象在Python中始终具有相同的哈希值。
>>> 1 == 1.0 True >>> hash(1) == hash(1.0) True
注意: 具有不同值的对象也可能具有相同的哈希值(哈希冲突)。
- 当执行
some_dict[5] = "Python"
语句时,因为Python将5
和5.0
识别为some_dict
的同一个键,所以已有值 "JavaScript" 就被 "Python" 覆盖了。
未完待续。
网友评论