数据编码和处理

问题:

  你想读写一个CSV 格式的文件

解决方案:

  对于大多数的CSV 格式的数据读写问题,都可以使用csv 库。例如:假设你在一个名叫stocks.csv 文件中有一些股票市场数据,就像这样:

 1 import csv
 2 
 3 '''
 4 #以元祖类型,写入csv格式的数据
 5 headers = ['Symbol','Price','Date','Time','Change','Volume']
 6 rows = [('AA', 39.48, '6/11/2007', '9:36am', -0.18, 181800),
 7         ('AIG', 71.38, '6/11/2007', '9:36am', -0.15, 195500),
 8         ('AXP', 62.58, '6/11/2007', '9:36am', -0.46, 935000),
 9         ("BA",  98.31, "6/11/2007", "9:36am", +0.12, 104800)
10         ]
11 
12 with open('stocks.csv', 'w') as f:
13     f_csv = csv.writer(f)
14     f_csv.writerow(headers)
15     for row in rows:
16         f_csv.writerow(row)
17 
18 '''
19 
20 #以字典类型写入csv的数据
21 headers = ['Symbol', 'Price', 'Date', 'Time', 'Change', 'Volume']
22 rows = [{'Symbol':'AA', 'Price':39.48, 'Date':'6/11/2007',
23         'Time':'9:36am', 'Change':-0.18, 'Volume':181800},
24         {'Symbol':'AIG', 'Price': 71.38, 'Date':'6/11/2007',
25         'Time':'9:36am', 'Change':-0.15, 'Volume': 195500},
26         {'Symbol':'AXP', 'Price': 62.58, 'Date':'6/11/2007',
27         'Time':'9:36am', 'Change':-0.46, 'Volume': 935000},
28         ]
29 
30 with open('stocks.csv','w') as f:
31     f_csv = csv.DictWriter(f, headers)
32     f_csv.writeheader()
33     f_csv.writerows(rows)
34 
35 
36 
37 #第一种方式
38 print('第一种输出'.center(100, '*'))
39 with open('stocks.csv') as f:
40     f_csv = csv.reader(f, delimiter=',')
41     headers = next(f_csv)
42     for row in f_csv:
43         print(row)
44         #print(row[0])
45 
46 #另外一种使用namedtuple的方式,可以通过row.Symbol来获取值
47 from collections import namedtuple
48 
49 print('第二种输出'.center(100, '-'))
50 with open('stocks.csv') as f:
51     f_csv = csv.reader(f)
52     headings = next(f_csv)
53     Row = namedtuple('Row', headings)
54     for r in f_csv:
55         row = Row(*r)
56         print(row)
57         #print(row.Symbol)
58 
59 
60 #第三种输出方式,把数据放到有序字典中
61 print('第三种输出'.center(100, '~'))
62 with open('stocks.csv') as f:
63     f_csv = csv.DictReader(f)
64     for row in f_csv:
65         print(row)
66         #print(row['Symbol'])

以上代码执行的结果为:

***********************************************第一种输出************************************************
['AA,39', '48,6/11/2007,9:36am,-0', '18,181800']
['AIG,71', '38,6/11/2007,9:36am,-0', '15,195500']
['AXP,62', '58,6/11/2007,9:36am,-0', '46,935000']
-----------------------------------------------第二种输出------------------------------------------------
Row(Symbol='AA', Price='39.48', Date='6/11/2007', Time='9:36am', Change='-0.18', Volume='181800')
Row(Symbol='AIG', Price='71.38', Date='6/11/2007', Time='9:36am', Change='-0.15', Volume='195500')
Row(Symbol='AXP', Price='62.58', Date='6/11/2007', Time='9:36am', Change='-0.46', Volume='935000')
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~第三种输出~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OrderedDict([('Symbol', 'AA'), ('Price', '39.48'), ('Date', '6/11/2007'), ('Time', '9:36am'), ('Change', '-0.18'), ('Volume', '181800')])
OrderedDict([('Symbol', 'AIG'), ('Price', '71.38'), ('Date', '6/11/2007'), ('Time', '9:36am'), ('Change', '-0.15'), ('Volume', '195500')])
OrderedDict([('Symbol', 'AXP'), ('Price', '62.58'), ('Date', '6/11/2007'), ('Time', '9:36am'), ('Change', '-0.46'), ('Volume', '935000')])

总结: 

  默认情况下,csv 库可识别Microsoft Excel 所使用的CSV 编码规则。这或许也是最常见的形式,并且也会给你带来最好的兼容性。然而,如果你查看csv 的文档,就会发现有很多种方法将它应用到其他编码格式上(如修改分割字符等),可以再reader的时候指定delimiter='分隔符'

读写JSON 数据

问题:

  你想读写JSON(JavaScript Object Notation) 编码格式的数据

解决方案:

  json 模块提供了一种很简单的方式来编码和解码JSON 数据。其中两个主要的函数是json.dumps() 和json.loads() ,要比其他序列化函数库如pickle 的接口少得多。下面演示如何将一个Python 数据结构转换为JSON: 

 1 import json
 2 
 3 data = {
 4     'name': 'ACEM',
 5     'shares': 100,
 6     'price': 543.23
 7 }
 8 
 9 #把字典变成json类型,其实就给字典外面套了一件衣服,变成他妈的一个字符串而已
10 json_str = json.dumps(data)
11 print('json_str type', type(json_str))
12 print('json_str', json_str)
13 
14 #把json过的数据还原回来
15 data = json.loads(json_str)
16 print('json loads data type', type(data))
17 print('json loads data', data)
18 
19 
20 #处理文件,把信息保存到文本中
21 print('保存data的信息到本地data.json中')
22 with open('data.json', 'w') as f:
23     json.dump(data , f)
24 
25 
26 #从本地的文本中读取信息
27 print('从本地文件data.json中获取数据')
28 with open('data.json', 'r') as f:
29     dump_data = json.load(f)
30 print('dump_data :',dump_data)

以上代码执行的结果为:

json_str type <class 'str'>
json_str {"name": "ACEM", "shares": 100, "price": 543.23}
json loads data type <class 'dict'>
json loads data {'name': 'ACEM', 'shares': 100, 'price': 543.23}
保存data的信息到本地data.json中
从本地文件data.json中获取数据
dump_data : {'name': 'ACEM', 'shares': 100, 'price': 543.23}

 

如果你试着去检查JSON 解码后的数据,你通常很难通过简单的打印来确定它的结构,特别是当数据的嵌套结构层次很深或者包含大量的字段时。为了解决这个问题,可以考虑使用pprint 模块的pprint() 函数来代替普通的print() 函数。它会按照key 的字母顺序并以一种更加美观的方式输出。下面是一个演示如何漂亮的打印输出Twitter 上搜索结果的例子:

1 from pprint import pprint
2 
3 api_resp = {"errors":[{"message":"The Twitter REST API v1 is no longer active. Please migrate to API v1.1. https://dev.twitter.com/docs/api/1.1/overview.","code":64}]}
4 print(api_resp)
5 
6 #格式化输出更加的漂亮了~
7 pprint(api_resp)

以上代码执行的结果为:

{'errors': [{'message': 'The Twitter REST API v1 is no longer active. Please migrate to API v1.1. https://dev.twitter.com/docs/api/1.1/overview.', 'code': 64}]}
{'errors': [{'code': 64,
             'message': 'The Twitter REST API v1 is no longer active. Please '
                        'migrate to API v1.1. '
                        'https://dev.twitter.com/docs/api/1.1/overview.'}]}

一般来讲,JSON 解码会根据提供的数据创建dicts 或lists。如果你想要创建其他类型的对象,可以给json.loads() 传递object pairs hook 或object hook 参数。例如,下面是演示如何解码JSON 数据并在一个OrderedDict 中保留其顺序的例子:

1 from collections import OrderedDict
2 import json
3 s = '{"name": "ACME", "shares": 50, "price": 490.1}'
4 
5 data = json.loads(s, object_hook=OrderedDict)
6 print(data)
7 #在编码JSON 的时候,还有一些选项很有用。如果你想获得漂亮的格式化字符串后输出,可以使用json.dumps() 的indent 参数
8 print(json.dumps(data, indent=5))

以上代码执行的结果为:

OrderedDict([('name', 'ACME'), ('shares', 50), ('price', 490.1)])
{
     "name": "ACME",
     "shares": 50,
     "price": 490.1
}

与关系型数据库的交互

问题:

  你想在关系型数据库中查询、增加或删除记录

解决方案:

  Python 中表示多行数据的标准方式是一个由元组构成的序列。例如:

 1 import sqlite3
 2 
 3 stocks = [
 4     ('GOOG', 100, 490.1),
 5     ('AAPL', 50, 545.75),
 6     ('FB', 150, 7.45),
 7     ('HPQ', 75, 33.2),
 8 ]
 9 
10 #连接数据库
11 db = sqlite3.connect('database.db')
12 #生成数据库游标
13 cursor = db.cursor()
14 #执行sql语句,创建一张portfolio的表
15 cursor.execute('create table portfolio (symbol text, shares integer, price real)')
16 #提交
17 db.commit()
18 
19 #插入多条数据
20 cursor.executemany('insert into portfolio values (?,?,?)', stocks)
21 db.commit()
22 
23 #执行查询语句
24 for row in db.execute('select * from portfolio'):
25     print(row)
26 
27 #接收用户参数的查询,必须确保你使用下面这样的占位符‘‘?‘‘来进行引用参数:
28 min_price = 100
29 for row in db.execute('select * from portfolio where price >= ?',(min_price,)):
30     print(row)

  

编码和解码十六进制数

问题:

  你想将一个十六进制字符串解码成一个字节字符串或者将一个字节字符串编码成一个十六进制字符串

解决方案:

  如果你只是简单的解码或编码一个十六进制的原始字符串,可以使用 binascii模块。例如:

 1 import binascii
 2 
 3 s = b'hello'
 4 #把bytes转换成十六进制
 5 h = binascii.b2a_hex(s)
 6 print("十六进制:", h)
 7 
 8 #把十六进制在转换成bytes
 9 s = binascii.a2b_hex(h)
10 print('bytes:', s)
11 
12 #另外一种方法
13 import base64
14 h = base64.b16encode(s)
15 print(h)
16 print(base64.b16decode(h))

以上代码执行的结果为:

十六进制: b'68656c6c6f'
bytes: b'hello'
b'68656C6C6F'
b'h

编码解码Base64 数据

问题:

  你需要使用Base64 格式解码或编码二进制数据

解决方案:

  base64 模块中有两个函数b64encode() and b64decode() 可以帮你解决这个问题。例如:

1 import base64
2 
3 s = b'Hello'
4 a = base64.b64encode(s)
5 print("转码成base64格式的:", a)
6 print("解码成base64格式的:", base64.b64decode(a))
7 
8 #转换成ASCII码
9 print('ascii码格式的:', base64.b64encode(s).decode('ascii'))

以上代码执行的结果为:

转码成base64格式的: b'SGVsbG8='
解码成base64格式的: b'Hello'
ascii码格式的: SGVsbG8
原文地址:https://www.cnblogs.com/demon89/p/7291123.html