3

常用内置对象操作

 2 years ago
source link: https://3wapp.github.io/Python/buildin_type.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

1. 0x01 string

1.1. 编码

# unicode
chinese = '\u4e2d\u6587'
>>> print chinese.decode('unicode-escape')
中文

1.2. 基本操作

>>> "a" + "b"
'ab'
>>> "a" * 3
'aaa'
>>> ",".join(["a", "b", "c"])           # 合并多个字符串
'a,b,c'
>>> "a,b,c".split(",")                  # 按指定字符分割
['a', 'b', 'c']
>>> "a\nb\r\nc".splitlines()            # 按行分割
['a', 'b', 'c']
>>> "a\nb\r\nc".splitlines(True)        # 分割后,保留换行行符。
['a\n', 'b\r\n', 'c']
>>> "abc".startswith("ab"), "abc".endswith("bc")!       # 判断是否以特定子子串开始或结束。
True, True
>>> "abc".upper(), "Abc".lower()        # 大大小小写转换。
'ABC', 'abc'
>>> "abcabc".find("bc"), "abcabc".find("bc", 2)         # 可指定查找起始结束位置。
1, 4
>>> " abc".lstrip(), "abc ".rstrip(), " abc ".strip()   # 剔除前后空格。
'abc', 'abc', 'abc'
>>> "abc".strip("ac")                   # 可删除指定的前后缀字符。
'b'
>>> "abcabc".replace("bc", "BC")        # 可指定替换次数。
'aBCaBC'
>>> "a\tbc".expandtabs(4)               # 将 tab 替换成空格。
'a    bc'
>>> "123".ljust(5, '0'), "456".rjust(5, '0'), "abc".center(10, '*')     # 填充
'12300', '00456', '***abc****'
>>> "123".zfill(6), "123456".zfill(4)   # 数字填充
'000123', '123456'

1.3. 格式化

Python 提供了两种字符串格式化方方法

  1. %[(key)][flags][width][.precision]typecode

标记: - 左对齐, + 数字符号, # 进制前缀, 或者用用空格、0 填充。

>>> "%(key)s=%(value)d" % dict(key = "a", value = 10)       # key
'a=10'
>>> "[%-10s]" % "a"         # 左对齐
'[a         ]'
>>> "%+d, %+d" % (-10, 10)  # 数字符号
'-10, +10'
>>> "%010d" % 3             # 填充
'0000000003'
>>> "%.2f" % 0.1234         # 小小数位
'0.12'
>>> "%#x, %#X" % (100, 200) # 十十六进制、前缀、大大小小写
'0x64, 0XC8'
>>> "%s, %r" % (m, m)       # s: str(); r: repr()
'test..., <__main__.M object at 0x103c4aa10>'
  1. format 方方法支支持更多的数据类型,包括列表、字典、对象成员等

{field!convertflag:formatspec}

格式化规范: formatspec: [[fill]align][sign][#][0][width][.precision][typecode]

>>> "{key}={value}".format(key="a", value=10)   # 使用用命名参数
'a=10'
>>> "{0},{1},{0}".format(1, 2)                  # field 可多次使用用
'1,2,1'
>>> "{0:,}".format(1234567)                     # 千分位符号 
'1,234,567'
>>> "{0:,.2f}".format(12345.6789)               # 千分位,带小小数位。
'12,345.68'
>>> "[{0:<10}], [{0:^10}], [{0:*>10}]".format("a")! # 左中右对齐,可指定填充字符。
'[a       ], [    a     ], [*********a]'
>>> import sys
>>> "{0.platform}".format(sys)          # 成员
'linux2'
>>> "{0[a]}".format(dict(a=10, b=20))   # 字典
'10'
>>> "{0[5]}".format(range(10))          # 列表
'5'

另有 string.Template 模板可供使用用。该模块还定义了各种常见的字符序列。

>>> from string import letters, digits, Template
>>> letters`        # 字母母表
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> digits          # 数字表
'0123456789'
>>> Template("$name, $age").substitute(name = "User1", age = 20)    # 模板替换。
'User1, 20'
>>> Template("${name}, $age").safe_substitute(name = "User1")       # 没找到值,不会抛出异常。
'User1, $age'

2. 0x02 字符串数字转换

二进制: ‘0b’ 开头 八进制: ‘0o’ 开头 十六进制: ‘0x’ 开头

  • 整数 <==> 字符串
# 十六进制
hex()       hex(number) -> string
> hex(10) ==> '0xa'

# 十进制
int()       int(x, base=10) -> int or long
> int('0b100', 0) ==> 4
> int('0b100', 2) ==> 4
> int('0x10', 16) ==> 16
> int('10', 16)   ==> 16

# 二进制
bin()       bin(number) -> string
> bin(4) ==> '0b100'

# 八进制
oct()       oct(number) -> string
> oct(17) ==> '021'

"{0:b}".format(4) ==> '100'
  • 整数 <==> 字节串

short:2字节, long:4字节

import struct

struct.unpack('<HH', bytes(b'\x01\x00\x00\x00')) ==> (1,0)
struct.unpack('<L', bytes(b'\x01\x00\x00\x00'))  ==> (1,)

struct.pack('<HH', 1,2)    ==> '\x01\x00\x02\x00'
struct.pack('<LL', 1,2)    ==> '\x01\x00\x00\x00\x02\x00\x00\x00'
  • 16进制串 <==> 字符串
'abc'.encode('hex')     ==> '616263'
binascii.b2a_hex('abc') ==> '616263'
binascii.hexlify('abc') ==> '616263'

'616263'.decode('hex')      ==> 'abc'
binascii.a2b_hex('616263')  ==> 'abc'
binascii.unhexlify('616263')==> 'abc'
  • 字符串 <==> 字节串
  • unicode

\u 后面是十六进制的Unicode码

+ prefix u

u‘中文’ ==> u'\u4e2d\u6587'

+ unicode 强制转换

要求 python文件中指定了对应的编码类型;并且对应的python文件的确是以该编码方式保存的
# -*- coding: utf-8 -*-

import sys

reload(sys)
sys.setdefaultencoding("utf-8")

s = unicode('中文')

>>> u'\u4e2d\u6587'
  • unicode <==> string

unicode ==> string : encode

string ==> unicode: decode

3. 0x03 编码

Python 2.x 默认采用用 ASCII 编码。为了完成编码转换,必须和操作系统字符编码统一一起来。

>>> import sys, locale
>>> sys.getdefaultencoding()            # Python 默认编码。
'ascii'
>>> c = locale.getdefaultlocale(); c    # 获取当前系统编码。
('zh_CN', 'UTF-8')
>>> reload(sys)                         # setdefaultencoding 在被初始化时被 site.py 删掉了。
<module 'sys' (built-in)>
>>> sys.setdefaultencoding(c[1])        # 重新设置默认编码。

str、unicode 都提供了 encode 和 decode 编码转换方方法。

  • encode: 将默认编码转换为其他编码。
  • decode: 将默认或者指定编码字符串转换为 unicode

标准库 codecs 模块用用来处理更复杂的编码转换

3.1. base64

  • characters set
ABCDEFGHIJKLMNOP
QRSTUVWXYZabcdef
ghijklmnopqrstuv
wxyz0123456789+/

4. 0x04 list

4.1. 基本操作

>>> []                          # 空列表
>>> ['a', 'b'] * 3   
['a', 'b', 'a', 'b', 'a', 'b']
>>> ['a', 'b'] + ['c', 'd']     # 连接多个列表
['a', 'b', 'c', 'd']
>>> list("abcd")                # 将序列类型或迭代器转换为列表
['a', 'b', 'c', 'd']
>>> [x for x in range(3)]       # 生生成器表达式
[0, 1, 2]

>>>l = list("abcbc")
>>>l[1:-1]                      # 切片
['b', 'c', 'b']
>>> l.count('b')                # 统计元素项
2
>>> l.index('b', 2)             # 从指定位置查找项,返回序号
3
>>> l.append('d')               # 追加元素
>>> l
['a', 'b', 'c', 'b', 'c', 'd']
>>> l.insert(1, 5)              # 指定位置插入元素
>>> l
['a', 5, 'b', 'c', 'b', 'c', 'd']
>>> l.extend(range(2))          # 合并列表
>>> l
['a', 5, 'b', 'c', 'b', 'c', 'd', 0, 1]
>>> l.remove('b')               # 移除第一个指定元素
>>> l
['a', 5, 'c', 'b', 'c', 'd', 0, 1]
>>> l.pop(0)                    # 弹出指定位置的元素(默认最后项)
'a'
>>> l
[5, 'c', 'b', 'c', 'd', 0, 1]

4.2. bisect 向有序列表中插入入元素

>>> import bisect
>>> l = ["a", "d", "c", "e"]
>>> l.sort()
>>> l
['a', 'c', 'd', 'e']
>>> bisect.insort(l, "b")
>>> l
['a', 'b', 'c', 'd', 'e']
>>> bisect.insort(l, "d")
>>> l
['a', 'b', 'c', 'd', 'd', 'e']

4.3. array

某些时候,可以考虑用用数组代替列表。 和列表存储对象指针不同,数组直接内嵌数据,既省了创建 对象的内存开销,又又提升了读写效率。

>>> import array
>>> a = array.array("l", range(10))     # 用用其他序列类型初始化数组。
>>> a
array('l', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.tolist()                          # 转换为列表。
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a = array.array("c")                # 创建特定类型数组。
>>> a.fromstring("abc")                 # 从字符串添加元素。
>>> a
array('c', 'abc')
>>> a.fromlist(list("def"))             # 从列表添加元素。
>>> a
array('c', 'abcdef')
>>> a.extend(array.array("c", "xyz"))   # 合并列表或数组。
>>> a
array('c', 'abcdefxyz')

5. 0x05 tuple

  • 只读对象,元组和元素指针数组内存是一一次性连续分配的
  • 虚拟机缓存 n 个元素数量小小于 20 的元组复用用对象

在编码中,应该尽可能用用元组代替列表。除内存复用用更高高效外,其只读特征更利于并行行开发

5.1. 基本操作:

>>> a = (4)             # 少了逗号,就成了普通的括号运算符了
>>> type(a)
<type 'int'>
>>> a = (4,)            # 这才是元组
>>> type(a)
<type 'tuple'>
>>> s = tuple("abcadef")! ! ! # 将其他序列类型转换成元组。
>>> s
('a', 'b', 'c', 'a', 'd', 'e', 'f')
>>> s.count("a")        # 元素统计。
2
>>> s.index("d")        # 查找元素,返回序号
4

5.2. 标准库 namedtuple

可用用名字访问元素项。

>>> from collections import namedtuple
>>> User = namedtuple("User", "name age")       # 空格分隔字段名,或使用用迭代器。
>>> u = User("user1", 10)
>>> u.name, u.age
('user1', 10)

其实 namedtuple 并不是元组,而而是利用用模板动态创建的自自定义类型

6. 0x06 dict

字典 (dict) 采用用开放地址法的哈希表实现

  • 自自带元素容量为 8 的 smalltable,只有 "超出" 时才到堆上额外分配元素表内存。
  • 虚拟机缓存 80 个字典复用用对象,但在堆上分配的元素表内存会被释放。
  • 按需动态调整容量。扩容或收缩操作都将重新分配内存,重新哈希
  • 删除元素操作不会立立即收缩内存

6.1. 创建字典

>>> {}              # 空字典
>>> {"a":1, "b":2}  # 普通构造方方式
>>> dict(a = 1, b = 2)          # 构造
{'a': 1, 'b': 2}
>>> dict((["a", 1], ["b", 2]))  # 用两个序列类型构造字典
{'a': 1, 'b': 2}
>>> dict(zip("ab", range(2)))   # 同上
{'a': 0, 'b': 1}
>>> dict(map(None, "abc", range(2)))    #同上
{'a': 0, 'c': None, 'b': 1}
>>> dict.fromkeys("abc", 1)     # 用序列作 key, 并提供默认的 value
{'a': 1, 'c': 1, 'b': 1}
>>> {k:v for k, v in zip("abc", range(3))}      # 使用用生生成表达式构造字典。
{'a': 0, 'c': 2, 'b': 1}

6.2. 基本操作

>>> d = {"a":1, "b":2}
>>> "b" in d            # 判断是否包含 key
True
>>> d = {"a":1, "b":2}  # 删除 k/v
>>> del d["b"]
>>> d
{'a': 1}
>>> d = {"a":1}
>>> d.update({"c": 3})  # 合并
>>> d
{'a': 1, 'c': 3}
>>> d = {"a":1, "b":2}
>>> d.pop("b")          # 弹出
>>> d
(2, {'a': 1})
>>> d = {"a":1, "b":2}
>>> d.popitem()         # 弹出 (key, value)
('a', 1)

# 默认返回值
>>> d = {"a":1, "b":2}
>>> d.get("c")              # 如果没有对应 key, 返回 None
None
>>> d.get("d", 123)         # 如果没有对应 key,返回缺省值。
>>> d.setdefault("a", 100)  # key 存在,直接返回 value。
1
>>> d.setdefault("c", 200)  # key 不存在,先设置,后返回。
200
>>> d
{'a': 1, 'c': 200, 'b': 2}

6.3. 迭代器操作

>>> d = {"a":1, "b":2}
>>> d.keys()
['a', 'b']
>>> d.values()
[1, 2]
>>> d.items()
[('a', 1), ('b', 2)]
>>> for k in d: print k, d[k]
a 1
b 2
>>> for k, v in d.items(): print k, v
a 1
b 2

对于大大字典,调用用 keys()、values()、items() 会构造同样巨大大的列表。建议用用迭代器替代,以减 少内存开销

>>> d = {"a":1, "b":2}
>>> d.iterkeys()
<dictionary-keyiterator object at 0x10de82cb0>
>>> d.itervalues()
<dictionary-valueiterator object at 0x10de82d08>
>>> d.iteritems()
<dictionary-itemiterator object at 0x10de82d60>
>>> for k, v in d.iteritems():
...    print k, v
a 1
b 2

6.4. 视图

要判断两个字典间的差异,使用用视图是最简便的做法。

>>> d1 = dict(a = 1, b = 2)
>>> d2 = dict(b = 2, c = 3)
>>> d1 & d2                 # 字典不支支持该操作。
TypeError: unsupported operand type(s) for &: 'dict' and 'dict'
>>> v1 = d1.viewitems()
>>> v2 = d2.viewitems()
>>> v1 & v2                 # 交集
set([('b', 2)]) 
>>> v1 | v2                 # 并集
set([('a', 1), ('b', 2), ('c', 3)])
>>> v1 - v2                 # 差集 (仅 v1 有,v2 没有的)
set([('a', 1)])
>>> v1 ^ v2                 # 对称差集 (不会同时出现在 v1 和 v2 中)
set([('a', 1), ('c', 3)])
>>> ('a', 1) in v1          # 判断
True

# 更新字典内容
>>> a = dict(x=1)
>>> b = dict(x=10, y=20)
39>>> a.update({k:b[k] for k in a.viewkeys() & b.viewkeys()})
>>> a
{'x': 10}

视图会和字典同步变更

>>> d = {"a": 1}
>>> v = d.viewitems()
>>> v
dict_items([('a', 1)])
>>> d["b"] = 2
>>> v
dict_items([('a', 1), ('b', 2)])
>>> del d["a"]
>>> v
dict_items([('b', 2)])

6.5. 扩展

当访问的 key 不存在时, defaultdict 自自动调用用 factory 对象创建所需键值对。factory 可以是任何无无参数函数或 callable 对象

>>> from collections import defaultdict
>>> d = defaultdict(list)       # key "a" 不存在,直接用用 list() 函数创建一一个空列表作为 value。
>>> d["a"].append(1)

>>> d["a"].append(2)
>>> d["a"]
[1, 2]

字典是哈希表,默认迭代是无无序的。如果希望按照元素添加顺序输出结果,可以用用 OrderedDict。

>>> from collections import OrderedDict
>>> d = dict()
>>> d["a"] = 1
>>> d["b"] = 2
>>> d["c"] = 3
>>> for k, v in d.items(): print k, v           # 并非非按添加顺序输出。
a 1
c 3
b 2
>>> od = OrderedDict()
>>> od["a"] = 1
>>> od["b"] = 2
>>> od["c"] = 3
>>> for k, v in od.items(): print k, v          # 按添加顺序输出。
a 1
b 2
c 3
>>> od.popitem()                                # 按 LIFO 顺序弹出。
('c', 3)
>>> od.popitem()
('b', 2)
>>> od.popitem()
('a', 1)

7. 0x07 set

集合 (set) 用用来存储无无序不重复对象。所谓不重复对象,除了不是同一一对象外,还包括 "值" 不能相同。集合只能存储可哈希对象,一一样有只读版本 frozenset。

判重公式: (a is b) or (hash(a) == hash(b) and eq(a, b))

在内部实现上,集合和字典非非常相似,除了 Entry 没有 value 字段。集合不是序列类型,不能像列表那样按序号访问,也不能做切片片操作

>>> s = set("abc")              # 通过序列类型初始化。
set(['a', 'c', 'b'])
>>> {v for v in "abc"}          # 通过构造表达式创建
set(['a', 'c', 'b'])
>>> "b" in s                    # 判断元素是否在集合中
True
>>> s.add("d")                  # 添加元素
>>> s
set(['a', 'c', 'b', 'd'])
>>> s.remove("b")               # 移除元素
>>> s
set(['a', 'c', 'd'])
>>> s.discard("a")              # 如果存在,就移除
>>> s
set(['c', 'd'])
>>> s.update(set("abcd"))       # 合并集合
>>> s
set(['a', 'c', 'b', 'd'])
>>> s.pop()                     # 弹出元素
'a'
>>> s
set(['c', 'b', 'd'])

7.1. 集合运算

>>> "c" in set("abcd")          # 判断集合中是否有特定元素
>>> set("abc") is set("abc")
False
>>> set("abc") == set("abc")    # 相等判断
True
>>> set("abc") != set("abc")    # 不等判断
False
>>> set("abcd") >= set("ab")    # 超集判断 (issuperset)
True
>>> set("bc") < set("abcd")     # 子集判断 (issubset)
True
>>> set("abcd") | set("cdef")   # 并集 (union)
set(['a', 'c', 'b', 'e', 'd', 'f'])
>>> set("abcd") & set("abx")    # 交集 (intersection)
set(['a', 'b'])
>>> set("abcd") - set("ab")     # 差集 (difference), 仅左边有,右边没有的
set(['c', 'd'])
>>> set("abx") ^ set("aby")     # 对称差集 (symmetric_difference)
set(['y', 'x'])                 # 不会同时出现在两个集合当中的元素
>>> set("abcd").isdisjoint("ab")    # 判断是否没有交集
False

7.2. 更新操作

>>> s = set("abcd")
>>> s |= set("cdef")        # 并集 (update)
>>> s
set(['a', 'c', 'b', 'e', 'd', 'f'])
>>> s = set("abcd")
>>> s &= set("cdef")        # 交集 (intersection_update)
>>> s
set(['c', 'd'])
>>> s = set("abx")
>>> s -= set("abcdy")       # 差集 (difference_update)
>>> s
set(['x'])
>>> s = set("abx")
>>> s ^= set("aby")         # 对称差集 (symmetric_difference_update)
>>> s
set(['y', 'x'])

集合和字典主键都必须是可哈希类型对象,但常用用的 list、dict、set、defaultdict、OrderedDict 都是不可哈希的,仅有 tuple、frozenset 可用用

>>> hash([])
TypeError: unhashable type: 'list'
>>> hash({})
TypeError: unhashable type: 'dict'
>>> hash(set())
TypeError: unhashable type: 'set'
>>> hash(tuple()), hash(frozenset())
(3527539, 133156838395276)

如果想把自自定义类型放入入集合,需要保证 hash 和 equal 的结果都相同才能去重

>>> class User(object):
...     def __init__(self, name):
...         self.name = name
>>> hash(User("tom"))           # 每次的哈希结果都不同
279218517
>>> hash(User("tom"))
279218521
>>> class User(object):
...    def __init__(self, name):
...        self.name = name
...    def __hash__(self):
...        return hash(self.name)
...    def __eq__(self, o):
...        if not o or not isinstance(o, User): return False
...        return self.name == o.name
>>> s = set()
>>> s.add(User("tom"))
>>> s.add(User("tom"))
>>> s
set([<__main__.User object at 0x10a48d150>])

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK