【筆記】《Python語言以及應用》- 數據操作

字符串:Unicode字符組成的序列
字節和字節數組:8 byte組成的序列

1. 編碼和解碼

編碼:將Unicode字符串轉化為一系列字節的過程

# str類型
snowman = '\u2603'
len(snowman)  # 1 只包含一個Unicode字符串,與所存儲的字節數無關

# bytes類型
ds = snowman.encode('utf-8')  # b'\xe2\x98\x83'
len(ds) # 3 占據3個字節的空間
# encode(encoding='utf-8', errors='strict') -> bytes
# 第一個參數為編碼方式,第二個參數為編碼異常的處理

# strict, 出錯時拋出UnicodeEncodeError錯誤

# ignore, 拋棄無法編碼的字符
snowman = 'abc\u2603'
ds = snowman.encode('ascii', 'ignore')
print(ds) # b'abc'
print(len(ds))  # 3

# replace, 將無法編碼的字符替換為?
snowman = 'abc\u2603'
ds = snowman.encode('ascii', 'replace')
print(ds) # b'abc?'
print(len(ds))  # 4

# backslashreplace, 將無法編碼的字符轉為\\u這種形式
snowman = 'abc\u2603'
ds = snowman.encode('ascii', 'backslashreplace')
print(ds) # b'abc\\u2603'
print(len(ds))  # 9

# xmlcharrefreplace, 將無法編碼的字符轉為字符串實體
snowman = 'abc\u2603'
ds = snowman.encode('ascii', 'xmlcharrefreplace')
print(ds) # b'abc☃'
print(len(ds))  # 10

解碼:將字節序列轉化為Unicode字符串的過程(注意編碼和解碼的格式必須一致,如都用utf-8,否則會得不到預期的值)

place = 'caf\u00e9'
place_bytes = place.encode('utf-8') # b'caf\xc3\xa9'
place2 = place_bytes.decode('utf-8')  # café

2. 格式化

舊的格式化:%
新的格式化:{}format

n = 42
f = 7.03
s = 'string cheese'

print('{} {} {}'.format(n, f, s)) # 默認
print('{2} {0} {1}'.format(f, s, n))  # 位置索引
print('{n} {f} {s}'.format(n=n, f=f, s=s))  # 關鍵字

d = {'n': n, 'f': f, 's': s}
print('{0[n]} {0[f]} {0[s]} {1}'.format(d, 'other'))  # 字典

print('{0:5d} {1:10f} {2:20s}'.format(n, f, s)) # 默認左對齊
print('{0:>5d} {1:>10f} {2:>20s}'.format(n, f, s))  # 左對齊
print('{0:<5d} {1:<10f} {2:<20s}'.format(n, f, s))  # 右對齊
print('{0:^5d} {1:^10f} {2:^20s}'.format(n, f, s))  # 居中對齊
print('{0:!^5d} {1:#^10f} {2:&^20s}'.format(n, f, s)) # 占位
print('{0:!^5d} {1:#^10.4f} {2:&^20.4s}'.format(n, f, s)) # 精度

3. 正則表達式

match檢查是否以...開頭

import re

source = 'Young man'
m = re.match('You', source)
if m:
  print(m.group())  # You

search返回第一次匹配成功的項

import re

source = 'Young man'
m = re.search('man', source)
if m:
  print(m.group())  # man

m1 = re.match('.*man', source)
if m1:
  print(m1.group())  # Young man

findall返回所有匹配項

import re

source = 'Young man'
m = re.findall('n.?', source)
print(m)  # ['ng', 'n'],沒有就返回[]

split類似于字符串的split,只不過這里是模式而不是文本

import re

source = 'Young man'
m = re.split('n', source)
print(m)  # ['You', 'g ma', '']

sub替換匹配,類似于字符串的replace, 只不過這里是模式而不是文本

import re

source = 'Young man'
m = re.sub('n', '?', source)
print(m)  # You?g ma?
模式 匹配
. 任意一個除\n外的字符
* 任意多個字符(包括0個)
+ 一個或多個字符
? 可選字符(0個或1個)
\d 一個數字字符
\w 一個字母或數字或下劃線字符
\s 空白符
\b 單詞邊界

特殊字符:

模式 匹配
. 任意一個除\n外的字符
* 任意多個字符(包括0個)
+ 一個或多個字符
? 可選字符(0個或1個)
\d 一個數字字符
\w 一個字母或數字或下劃線字符
\s 空白符
\b 單詞邊界
import string
import re

printable = string.printable

re.findall('\d', printable) # ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

re.findall('\s', printable) # [' ', '\t', '\n', '\r', '\x0b', '\x0c']

定義匹配的輸出

m.groups()獲得匹配的元組

import re

source = 'a dish of fish tonight.'

m = re.search(r'(. dish\b).*(\bfish)', source)
print(m.group())  # a dish of fish
print(m.groups()) # ('a dish', 'fish')

(?P<name>expr)匹配expr,并將結果存儲在名為name的組中

import re

source = 'a dish of fish tonight.'

m = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', source)
print(m.group())   # a dish of fish
print(m.group('DISH'))  # a dish
print(m.group('FISH'))  # fish
print(m.groups()) # ('a dish', 'fish')

4. 讀寫文件

open(filename, mode)
其中mode的第一個字母表明對文件的操作:

  • r表示讀模式
  • w表示寫模式(若文件不存在,則新創建;若存在則重寫新內容)
  • x表示文件不存在的情況下新創建并寫文件
  • a表示如果文件存在,在文件末尾追加寫內容

第二個字母:

  • t文本類型(默認)
  • b二進制文件

使用write()寫文件:

poem = '''
床前明月光,
疑是地上霜。
舉頭望明月,
低頭思故鄉。
'''

with open('a.txt', 'wt', encoding='utf-8') as fout:
  fout.write(poem)


# 數據分塊
with open('a.txt', 'wt', encoding='utf-8') as fout:
  size = len(poem)
  offset = 0
  chunk = 100
  while True:
    if offset > size:
      break
    fout.write(poem[offset:offset+chunk])
    offset += chunk

# 避免重寫
try:
  with open('a.txt', 'xt', encoding='utf-8') as fout:
    fout.write(poem)
except FileExistsError:
  print('文件已經存在')

使用read()、readline()、readlines()讀文件:

with open('a.txt', 'rt', encoding='utf-8') as fin:
  poem = fin.read()

# 每次讀一行
with open('a.txt', 'rt', encoding='utf-8') as fin:
  poem = ''
  while True:
    line = fin.readline()
    if not line:
      break
    poem += line

# 使用迭代器
with open('a.txt', 'rt', encoding='utf-8') as fin:
  poem = ''
  for line in fin:
    poem += line

# 讀入所有行,返回單行字符串的列表
with open('a.txt', 'rt', encoding='utf-8') as fin:
  lines = fin.readlines()
# 輸出 ['\n', '床前明月光,\n', '疑是地上霜。\n', '舉頭望明月,\n', '低頭思故鄉。\n']

tell()返回文件此刻的字節偏移量,seek(n)跳到文件字節偏移量為n的位置:

seek(offset, origin)

origin=0(默認), 從開頭偏移offset個字節
origin=1, 從當前位置偏移offset個字節
origin=2, 距離最后結尾處偏移offset個字節

with open('b', 'rb') as fin:
  print(fin.tell())   # 從0開始
  fin.seek(254, 0)    # 跳到254(返回最后兩個字節)
  print(fin.tell())   # 254
  fin.seek(1, 1)      # 在此基礎上前進一個字節
  print(fin.tell())   # 255
  data = fin.read()   # 一直讀到文件結尾 b'\xff'

print(data[0])  # 255
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容