Python 数据类型

bool
None、0、空字符串、以及没有元素的容器对象都可视为 False,反之为 True。
>>> map(bool, [None, 0, "", u"", list(), tuple(), dict(), set(), frozenset()])
[False, False, False, False, False, False, False, False, False]
虽然有点古怪,但 True、False 的确可以当数字使⽤用。
>>> int(True)
1
>>> int(False)
0
>>> range(10)[True]
1
>>> x = 5
>>> range(10)[x > 3]
1
int
在 64 位平台上,int 类型是 64 位整数 (sys.maxint),这显然能应对绝⼤大多数情况。整数是虚拟机
特殊照顾对象:
• 从堆上按需申请名为 PyIntBlock 的缓存区域存储整数对象。
• 使⽤用固定数组缓存 [-5, 257) 之间的⼩小数字,只需计算下标就能获得指针。
• PyIntBlock 内存不会返还给操作系统,直⾄至进程结束。
24
看看 "⼩小数字" 和 "⼤大数字" 的区别:
>>> a = 15
>>> b = 15
>>> a is b
True
>>> sys.getrefcount(a)
47
>>> a = 257
>>> b = 257
>>> a is b
False
>>> sys.getrefcount(a)
2
因 PyIntBlock 内存只复⽤用不回收,同时持有⼤大量整数对象将导致内存暴涨,且不会在这些对象被
回收后释放内存,造成事实上的内存泄露。
⽤用 range 创建⼀一个巨⼤大的数字列表,这就需要⾜足够多的 PyIntBlock 为数字对象提供存储空间。但
换成 xrange 就不同了,每次迭代后,数字对象被回收,其占⽤用内存空闲出来并被复⽤用,内存也就
不会暴涨了。
运⾏行下⾯面测试代码前,必须先安装 psutil 包,⽤用来获取内存统计数据。
$ sudo easy_install -U psutil
$ cat test.py
#!/usr/bin/env python
import gc, os, psutil
def test():
x = 0
for i in range(10000000):? # xrange
x += i
return x
def main():
print test()
gc.collect()
p = psutil.Process(os.getpid())
25
print p.get_memory_info()
if __name__ == "__main__":
main()
对⽐比 range 和 xrange 所需的 RSS 值。
range: meminfo(rss=93339648L, vms=2583552000L)? # 89 MB
xrange: meminfo(rss=8638464L, vms=2499342336L)? # 8 MB
在实际开发中,很少会遇到这样的情形。就算是海量整数去重、排序,我们也可⽤用位图等算法来节
约内存使⽤用。Python 3 已经⽤用 xrange 替换掉了默认的 range,我们使⽤用 2.x 时稍微注意⼀一下即
可。
long
当超出 int 限制时, 会⾃自动转换成 long。 作为变⻓长对象,只要有内存⾜足够,⾜足以存储⽆无法想象的
天⽂文数字。
>>> a = sys.maxint
>>> type(a)
<type 'int'>
>>> b = a + 1? ? ? ? # 超出,⾃自动使⽤用 long 类型。
>>> type(b)
<type 'long'>
>>> 1 << 3000
12302319221611....890612250135171889174899079911291512399773872178519018229989376L
>>> sys.getsizeof(1 << 0xFFFFFFFF)
572662332
使⽤用 long 的机会不多,Python 也就没有必要专⻔门为其设计优化策略。
float
使⽤用双精度浮点数 (float),不能 "精确" 表⽰示某些⼗十进制的⼩小数值。尤其是 "四舍五⼊入 (round)" 的
结果,可能和预想不同。
>>> 3 / 2? ? ? # 除法默认返回整数,在 Python 3 中返回浮点数。
1
>>> float(3) / 2
1.5
26
>>> 3 * 0.1 == 0.3? ? # 这个容易导致莫名其妙的错误。
False
>>> round(2.675, 2)? ? # 并没有想象中的四舍五⼊入。
2.67
如果需要,可⽤用 Decimal 代替,它能精确控制运算精度、有效数位和 round 的结果。
>>> from decimal import Decimal, ROUND_UP, ROUND_DOWN
>>> float('0.1') * 3 == float('0.3')? ? ? ? ? # float 转型精度不同
False
>>> Decimal('0.1') * 3 == Decimal('0.3')? ? ? ? # decimal 没有问题
True
>>> Decimal('2.675').quantize(Decimal('.01'), ROUND_UP)? ? # 精确控制 round
Decimal('2.68')
>>> Decimal('2.675').quantize(Decimal('.01'), ROUND_DOWN)
Decimal('2.67')
在内存管理上,float 也采⽤用 PyFloatBlock 模式,但没有特殊的 "⼩小浮点数"。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值