python学习-操作数据

操作数据:

字符串:Unicode 字符组成的序列,用于存储文本数据。

字节和字节数组:8比特整数组成的序列,用于存储二进制数据。

文本字符串

Unicode

1、Python3中的Unicode字符串

Unicode:为每个字符赋予了一个特殊的数字编码,这些编码与具体平台、程序、语言无关。 Unicode Code Charts页面 (http://www.unicode.org/charts/)包含了目前已定义字符集的链接。最新版 (6.2)定义超过了 110000种字符。 Python3中的字符串是Unicode字符串而不是字节数据,这是与Python2相比最大的差别。

Python中的unicodedata模块提供了下面两个方向的转换函数: lookup()——接受不区分大小写的标准名称,返回一个Unicode字符; name()——接受一个Unicode字符,返回大写形式的名称。

def unicode_test(value):
    import unicodedata
    name = unicodedata.name(value)
    value2 = unicodedata.lookup(name)
    print(‘value=”%s”, name=”%s”, value2=”%s”’ %(value,name,value2))

unicode_test(‘$’)
value=”$”, name=”DOLLAR SIGN”, value2=”$”

指定特殊的编码:

 >>>import unicodedata
 >>>unicodedata.name('\u00e9')
   'LATIN SMALL LETTER E WITH ACUTE'
 >>>unicodedata.lookup('LATIN SMALL LETTER E WITH ACUTE')
    'é'
 >>> place = 'caf\u00e9'
 >>> place
    'café'
 >>> place = 'caf\N{LATIN SMALL LETTER E WITH ACUTE}'
 >>> place
    'café'
 >>> u_umlaut='\N{LATIN SMALL LETTER U WITH DIAERESIS}'
 >>> u_umlaut
    'ü'

2、使用UTF-8 编码和解码

当需要与外界进行数据交互时需要完成两件事情:

a、将字符串编码为字节; b、将字节解码为字符串。

UTF-8动态编码方案:

a、为ASCII 分配1字节; b、为拉丁语系(除西里尔语)的语言分配2字节; c、为其他的位于基本多语言平面的字符分配3字节; d、为剩下的字符分配4字节,这包括一些亚洲语言及符号。 UTF-8是Python、Linux以及HTML的标准文本编码格式。

3、编码

编码是将字符串转化为一系列字节的过程。字符串encode()函数接受的第一个参数是编码方式名。可选的编码方式有:

ascii 经典的7比特ASCII编码

utf-8 最常用的以8比特为单位的变长编码

latin-1 也被称为ISO 8859-1编码

cp-1252 Windows常用编码

unicode-escape Python中Unicode的转义文本格式,\uxxxx 或者 \uxxxxxxxx

可以将任意Unicode数据以UTF-8的方式进行编码

>>> snowman=’\u2603’
>>> len(snowman)   #snowman是一个仅包含一个字符的Unicode字符串
    1
>>> ds = snowman.encode(‘utf-8’)  
>>> len(ds)      #单个Unicode字符snowman占用了3字节的空间
    3
>>>ds      # ds 是一个bytes类型的变量
b’\xe2\x98\x83’

encode()函数可接受额外的第二个参数帮助避免编码异常,默认值是’strict’

>>> snowman.encode('ascii','strict')
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
snowman.encode('ascii','strict')
UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 0: ordinal not in range(128)
>>> snowman.encode('ascii','ignore')  #抛弃任何无法进行编码的字符
b’’
>>> snowman.encode(‘ascii’,’replace’)  #将所有无法进行编码的字符替换为?
b’?’
>>> snowman.encode(‘ascii’,’backslashreplace’) #创建一个和unicode-escape类似的Unicode字符串
b’\\u2603’

4、解码: 解码是将字节序列转化为Unicode字符串的过程。

>>> place = 'caf\u00e9'
>>> place
'café'
>>> type(place)
<class 'str'>
>>> place_bytes = place.encode('utf-8')
>>> place_tytes
Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    place_tytes
NameError: name 'place_tytes' is not defined
>>> place_bytes
b'caf\xc3\xa9'
>>> type(place_bytes)
<class 'bytes'>
>>> place2 = place_bytes.decode('utf-8')
>>> place2
'café'

## 格式化 ##

我们使用不同的格式化方法将变量插值(interpolate)到字符串中了,有两种格式化字符串的方式:旧时(old style)和新式(new style)。

1、旧式

数据转换类型:

%s 字符串

%d 十进制整数

%x 十六进制整数

%o 八进制整数

%f 十进制浮点数

%e 以科学计数法表示的浮点数

%g 十进制或科学计数法表示的浮点数

%% 文本值%本身

>>> ‘%s’ % 42
‘42’
>>> ‘%x’ % 42
‘2a’
>>> ‘%e’ % 7.03
‘7.030000e+00’
>>> ‘%d%%’ % 100
‘100%’
>>> n = 42
>>> f = 7.03
>>> s = ‘string cheese’
>>>’%d %f %s’ % (n,f,s)
’42 7.03 string cheese’
>>>’%10d %10f %10s’ % (n,f,s)  #为每个变量设定最小域宽为10个字符,右对齐
‘        42   7.030000 string cheese’
>>>’%10.4d %10.4f %10.4s’ % (n,f,s)  #设定最小域宽10,最大字符宽度为4
‘      0042   7.0300  stri’
>>>’%*.*d %*.*f %*.*s’ %(10,4,n,10,4,f,10,4,s)  #将域宽/字符宽度设定作为参数
‘      0042   7.0300  stri’

2、使用{}和format的新式格式化

>>> '{} {}   {}'.format(n,f,s)
'42 7.03   string chess'
>>>’{2} {0}   {1}’.format(f,s,n)  # 新式格式化可指定插入的顺序 0,1,2:参数的位置
’42 7.03   string chess’
>>> d={‘n’:42,’f’:7.03,’s’:’string cheese’}
>>> ‘{0[n]} {0[f]} {0[s]} {1}’.format(d,’other’) # {0}代表整个字典,{1}代表字典后面的字符串
’42 7.03 string cheese other’
>>> ‘{0:d} {1:f} {2:s}’.format(n,f,s)  #格式标识符放在 : 后面
’42 7.030000 string cheese’
>>>’{0:!^20s}’.format(‘BIG SALE’)  #把空格以外的填充字符放在 : 之后,任何排版赋(<、>、^)和宽度标识符之前即可。
‘!!!!!!BIG SALE!!!!!!’

3、使用正则表达式匹配

正则表达式(regular expression):位于标准库模块re中,定义一个匹配的模式(pattern)字符串以及一个匹配的对象:源(source)字符串

>>> result = re.match(‘You’, ‘Young Frankenstein’)  # ‘You’ 是模式,’Young Frankenstein’是源 match()函数用于查看源是否以模式开头。
>>> youpattern = re.compile(‘You’)  #对模式进行编译以加快匹配速度
>>> result = youpattern.match(‘Young Frankenstein’)  #直接使用已编译模式进行匹配

.match() 进行精准匹配

.search() 如果存在的话返回第一次成功匹配

.findall() 如果存在的话返回所有不重叠的匹配

.split() 根据pattern将source切分成若干段,返回由这些片段组成的列表

.sub() 需一个额外的参数replacement,把source中匹配的pattern替换为replacement

匹配功能的简单解释:

 * 代表任意一个它之前的字符;

 . 代表任意单一字符;

 .* 代表任意多个字符(包括0个);

 Frank是我们想要在源字符串中某处进行匹配的短语

二进制数据

需要了解字节序(endianness,处理器是如何将数据组织存储为字节的)以及整数的符号位(sign bit)之类的概念。

1、字节和字节数组:

. 字节是不可变的,像字节数据组成的元组; . 字节数组是可变的,像字节数据组成的列表。

>>> blist = [1,2,3,255]
>>> the_bytes = bytes(blist)
>>> the_bytes
b'\x01\x02\x03\xff'  #bytes类型值的表示是以b开头,接着一个单引号,后面跟十六进制数
>>> the_byte_array = bytearray(blist)
>>> the_byte_array
bytearray(b'\x01\x02\x03\xff')
>>>

2、使用struct转换二进制数据

可使用struct模块的功能将二进制数据转换为Python中的数据结构 http://upload.wikimedia.org/wikipedia/en/9/95/O'Reilly_logo.png 大眼猴图片

struct.unpack():将数据类型转换为字节,正确解读字节序列并将它们组装成Python中的数据类型。

width,height = struct.unpack(‘>LL’, daa[16:24])

其中:’>LL’ 格式串,用于指导unpack()正确解读

> 用于指明整数是以大端(big-endian)方案存储的;

每个 L 代表一个4字节的无符号常(unsigned long)整数

struct.pack():将Python数据转换为字节

>>> import struct
>>> struct.pack(‘>L’, 154)
b’\x00\x00\x00\x9a’
>>> struct.pack(‘>L’, 141)
b’\x00\x00\x00\x8d’

字节序标识符

标识符 字节序

< 小端(到文件)方案

> 大端(在网络)方案

格式标识符

标识符 描述 字节

x 跳过一个字节 1

b 有符号字节 1

B 无符号字节 1

h 有符号短整数 2

H 无符号短整数 2

i 有符号整数 4

I(大写i) 无符号整数 4

l 有符号长整数 4

L 无符号长整数 4

Q 无符号long long型整数 8

f 单精度浮点数 4

d 双精度浮点数 8

p 数量和字符 1+数量

s 字符 数量

类型标识符紧跟在字节标识符的后面,任何标识符前面都可以添加数字用于指定需要匹配的数量。

其他二进制数据工具

第三方开源包提供了更加直观定义和提取二进制数据的方法: bitstring(https://code.google.com/p/python-bitstring/) construct(http://construct.readthedocs.org/en/latest/) hachoir(https://bitbucket.org/haypo/hachoir/wiki/Home) binio(http://spika.net/py/binio/)

安装construct包:

$ pip install construct

使用binascii()转换字节/字符串

标准binascii模块提供了在二进制数据和多种字符串表示(十六进制、六十四进制、uuencoded,等等)之间转换的函数。

位运算符: a(十进制 5, 二进制0b0101) b(十进制1,二进制0b0001)

运算符 描述 示例 十进制结果 二进制结果

& 与 a&b 1 0b0001

| 或 a | b 5 0b0101

^ 异或 a ^ b 4 0b0100

~ 翻转 ~a -6 取决于int类型的大小

<< 左位移 a << 1 10 0b1010

>> 右位移 a >> 1 2 0b0010

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值