包括Python
中的常用数据类型。
int
在64
位平台上,int
类型是64
位整数:
- 从堆上按需申请名为
PyIntBlcok
的缓存区域存储整数对象 - 使用固定数组缓存
[-5, 257]
之间的小数字,只需计算下标就能获得指针 PyIntBlock
内存不会返还给操作系统,直至进程结束
根据第三点,如果使用range
创建巨大的数字列表,这就需要很大内存空间。但是换成xrange
,每次迭代之后数字对象被回收,其占用内存空间出来并被复用,内存就不会暴涨。(仅指python2
)。
当超出int
限制时,会自动转换成为long
。
float
在python2
中,/
默认返回整数,而python3
中默认返回浮点数。如果需要准确控制运算精度,有效位数和round
的结果,使用Decimal
代替。(但是建议往Decimal
传入字符串型的浮点数 – 为什么你需要少看垃圾博客以及如何在Python里精确地四舍五入
string
不太熟的方法
splitlines()
: 按行分割find()
: 查找lstrip()/rstrip()/strip()
: 剔除前后空格replace()
:替换字符expandtabs()
:将tab
替换成空格ljust()/rjust()/center()/zfill()
:填充字符编码
在计算机内存中,统一使用
Unicode
编码,当需要保存到硬盘或者需要传输的时候,转换为UTF-8
编码。py3
:
py2
:
因此代码中,最核心的部分应该使用Unicode
字符类型,即py3
中使用str
,py2
中使用unicode
。这两种字符类型没有相关联的二进制编码(原生的8
个比特值),因此如果要将Unicode
转换为二进制数据,应该使用encode
方法。而反过来,如果要二进制编码转化为Unicode
字符,必须使用decode
方法。py3
中的写法:
py2
中的写法:
需要注意的是两大陷阱:
在
py2
中,当一个str
类型仅仅包含7个比特的ASCII
码字符的时候,unicode
和str
实例看起来是一致的。因此可以采用:+
运算符合并str
和unicode
- 可以使用等价或者不等价运算符来比较
str
和unicode
实例 - 可以使用
unicode
来替换像%s
这种字符串中的格式化占位符
在
py3
中,涉及到文件的处理操作,例如采用内置的open
函数,会默认以utf8
编码,而在py2
中默认采用二进制的形式编码。举个例子,在py3
的情况下,会报错:
画重点
py3
中,bytes
是包含8
个比特位的序列,str
是包含unicode
的字符串,它们不能同时出现在操作符>
或者+
中。py2
中,str
是包含8
个比特位的序列,而unicode
是包含unicode
的字符串,二者可以同时出现在只包含7个比特的ASCII
码的运算中。- 使用工具函数来确保程序输入的数据是程序预期的类型,例如上面的
to_str
之类的函数。 - 总是使用
wb
和rb
模式来处理文件。
string.ascii_letters/digits
使用string
类的ascii_letters
或者digits
可以获得大小写字符,以及数字,避免自己写循环生成:
池化
使用intern()
可以把运行期动态生成的字符串池化:
dict
popitem()
setdefault(key, default=None)
fromkeys(it, [initial])
update
可以采用key=value
的形式:
也可以采用{key:value}
的形式:
也可以使用tuple
的形式:
对于大字典,调用keys()
、values()
、items()
会同样构造巨大的列表,因此可以使用迭代器(iterkeys()
、itervalues()
、iteritems()
)减少内存开销。
视图
判断两个字典间的差异,除了使用Counter
,也可以使用视图。
视图会和字典同步变更:大专栏 Python拾遗(2)r/>
collections.defaultdict
在实例化一个defaultdict
的时候,需要给构造方法提供一个可调用对象或者无参数函数,这个可调用对象会在__getitem__
(例如dd
是个defaultdict
,当dd[k]
时会调用此方法)碰到找不到的键的时候被调用,让__getitem__
返回某种默认值。如果在创建defaultdict
的时候没有指定可调用对象,查询不存在的键会触发KeyError
(这是由于__missing__
方法的缘故)。
使用一个类型初始化,当访问键值不存在时,默认值为该类型实例。
也可以使用不带参数的可调用函数进行初始化,当键值没有指定的时候,可以采用该函数进行初始化
简化为:
OrderedDict
字典是哈希表,默认迭代是无序的,如果需要元素按照添加顺序输出结果,可以使用OrderedDict
。
set
set
方法的pop
也是随机弹出的。集合和字典的主键都必须是可哈希类型对象。
如果需要将自定义类型放入集合中,需要保证hash
和equal
的结果都相同才行:
list
对于频繁增删元素的大型列表,应该考虑使用链表或者迭代器创建列表对象的方法(itertools
)。某些时候,可以考虑用数组(array
)代替列表,但是它只能放指定的数据类型:
向有序列表插入元素
Tuple
在对tuple
进行比较的时候,Python
会优先比较元组中下标为0
的元素,然后依次递增。有个很神奇的例子:
namedtuple
需要两个参数,一个是类名,另一个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
将数据变为
namedtuple
类:如果要进行更新,需要调用方法
_replace
:将字典数据转换成
namedtuple
: