Py3——数据编码和处理

读写CSV数据

对一个csv格式的文件进行读写

假设有下面这样的数据在一个 stu.csv 文件中

name,gender,height,weight
'xiaoming','man','170cm','56kg'
'xiaohua','man','162cm','52kg'
'xiaohong','woman','163cm','45kg'
'xiaozhuang','man','174cm','70kg'

下面将读取这些数据为一个元组序列

import csv
with open('stu.csv') as f:
    f_csv = csv.reader(f)
    #取出第一行数据
    headers = next(f_csv)
    #遍历其余数据
    for row in f_csv:
    '''在这里每一次读取都是一行数据,在python中以列表的方式存在,我们可以根据下标取出相对应列的数据
    '''

这种根据下标来取有时候可能会引起混乱,所以我们可以改善一下使用命名元组(去了解命名元组)来重写代码

from collections import namedtuple
with open('stu.csv') as f:
    f_csv = csv.reader(f)
    headers = next(f_csv)
    Row = namedtuple('Row',headers)
    for r in f_csv:
        row = Row(*r)

这样重写之后,访问 name 就可以使用 Row.name 而不是以前的 row[0] 了。

读取JSON数据

json 是 javascript 中的对象表示方法,也被许多语言所接纳,类似于python中的字典。

python中提供有json模块来对json数据进行编码和解码,其中两个主要的函数是 json.dunps() 和 json.loads()

# 将 python 数据结构转换为json
import json
data = {
'name':'ACME''shares':100,
'price':542.23
}
json_str = json.dumps(data)
#将json对象转换为python数据结构
data = json.loads(json_str)

如果要处理的对象是文件而不是字符串,可以使用 json.dump() 和 json.load() 来编码和解码 json数据

json编码支持的基本数据类型有 None, bool, int, float 和 str,以及包含这些数据类型的列表,元组和字典。
对于这种多种数据类型嵌套复杂的结构,可以使用pprint模块的pprint() 函数来以一种更美观的方式输出

解析简单的 XML 数据

使用 xml.etree.ElementTree 模块从简单的 xml文档中提取数据,以· Planet Python上的 Rss源作为展示实例。(ps:Rss是工作学习中获取信息的一种十分简便高效的方式,推荐大家学习使用)

from urllib.request import urlopen
from xml.etree.ElementTree import parse

u = urlopen('http://planet.python.org/rss20.xml')
doc = parse(u)

for item in doc.iterfind('channel/item')
    title = item.findtext('title')
    date = item.findtext('date')
    link = item.findtext('link')

    print(title,date)
    print(link)
    print()

xml.etree.ElementTree.parse() 函数解析整个XML文档并将器转换成一个文档对象,然后可以使用 find() iterfind() findtext() 等方法来搜索特定的XML元素,参数使用指定的标签名。python中关于页面解析的方法还有很多种

增量式解析大型XML文件

解析 Xml 文件过程中会占用大量的内存,就如同生成一个千万级的列表是一样的,对资源造成浪费同时也对效率造成很大影响。

iterparse模块是一种以生成器与迭代器思想来解析大型XML文件的

iterparse() 方法允许对XML文档进行增量操作。 使用时,你需要提供文件名和一个包含下面一种或多种类型的事件列表: start , end, start-ns 和 end-ns 。 由 iterparse() 创建的迭代器会产生形如 (event, elem) 的元组, 其中 event 是上述事件列表中的某一个,而 elem 是相应的XML元素。

将字典转换为XML

将一个python字典存储数据,并将它转换成xml格式

xml.etree.ElementTree 库除了可以用来做解析工作,还可以创建 XML 文档

from xml.etree.ElementTree import Element

def dict_to_xml(tag, d):
'''
Turn a simple dict of key/value pairs into XML
'''
elem = Element(tag)
for key, val in d.items():
    child = Element(key)
    child.text = str(val)
    elem.append(child)
return elem

s = { 'name': 'GOOG', 'shares': 100, 'price':490.1 }
e = dict_to_xml('stock', s)  # <Element 'stock' at 0x1004b64c8>
# 这里的e就是一个 Element 实例,可以使用 xml.etree.ElementTree 中的 tostring() 函数来转换成一个字节字符串
from xml.etree.ElementTree import tostring
tostring(e)
b'<stock><price>490.1</price><shares>100</shares><name>GOOG</name></stock>'

如果想给某个元素添加属性值,可以使用 set() 方法:

e.set('_id','1234')
tostring(e)
b'<stock _id="1234"><price>490.1</price><shares>100</shares><name>GOOG</name>
</stock>'

!!如果想给某个元素添加属性值,可以构造一个 OrderedDict 来代替一个普通的字典

当被限制只能构造字符串类型的值时

def dict_to_xml_str(tag, d):
    '''
    Turn a simple dict of key/value pairs into XML
    '''
    parts = ['<{}>'.format(tag)]
    for key, val in d.items():
        parts.append('<{0}>{1}</{0}>'.format(key,val))
    parts.append('</{}>'.format(tag))
    return ''.join(parts)

当字典的值中包含一些特殊字符的时候 比如’<’ , ‘>’ 会 被替换成 &lt;和 &gt;
这时可以使用 xml.sax.saxutils 中的 escape() 和 unescape() 函数。

from xml.sax.saxutils import escape, unescape
escape('<spam>')
'&lt;spam&gt;'
unescape(_)
'<spam>'

这里推荐 Element 实例而不是字符串,是因为 Elment 实例可以不用考虑解析XML文本的情况下通过多种方式被处理,在一个高级数据结构上完成你所有的操作,并在最后以字符串的形式将其输出

解析和修改 XML

读取一个xml文档,对其做一些修改,然后将结果写回xml文档中。

使用 xml.etree.ElementTree 模块可以很容易的处理这些任务。
pred.xml

<?xml version="1.0"?>
<stop>
    <id>14791</id>
    <nm>Clark &amp; Balmoral</nm>
    <sri>
        <rt>22</rt>
        <d>North Bound</d>
        <dd>North Bound</dd>
    </sri>
    <cr>22</cr>
    <pre>
        <pt>5 MIN</pt>
        <fd>Howard</fd>
        <v>1378</v>
        <rn>22</rn>
    </pre>
    <pre>
        <pt>15 MIN</pt>
        <fd>Howard</fd>
        <v>1867</v>
        <rn>22</rn>
    </pre>
</stop>

利用 ElementTree 来读取文档并做一些修改的例子:

from xml.etree.ElementTree import parse, Element
doc = parse('pred.xml')
root = doc.getroot()  # <Element 'stop' at 0x100770cb0>

# Remove a few elements
root.remove(root.find('sri'))
root.remove(root.find('cr'))
# Insert a new element after <nm>...</nm>
root.getchildren().index(root.find('nm'))  # 1
e = Element('spam')
e.text = 'This is a test'
root.insert(2, e)

# Write back to a file
doc.write('newpred.xml', xml_declaration=True)

处理后

<?xml version='1.0' encoding='us-ascii'?>
<stop>
    <id>14791</id>
    <nm>Clark &amp; Balmoral</nm>
    <spam>This is a test</spam>
    <pre>
        <pt>5 MIN</pt>
        <fd>Howard</fd>
        <v>1378</v>
        <rn>22</rn>
    </pre>
    <pre>
        <pt>15 MIN</pt>
        <fd>Howard</fd>
        <v>1867</v>
        <rn>22</rn>
    </pre>
</stop>

AND
修改一个XML文档结构是很容易的,但是你必须牢记的是所有的修改都是针对父节点元素, 将它作为一个列表来处理。例如,如果你删除某个元素,通过调用父节点的 remove() 方法从它的直接父节点中删除。 如果你插入或增加新的元素,你同样使用父节点元素的 insert() 和 append() 方法。 还能对元素使用索引和切片操作,比如 element[i] 或 element[i:j]

读写二进制数组数据

将一个二进制数组的结构化数据读写到Python元组中。

python 中可以使用 struct 模块处理二进制数据。可以将一个python元组列表写入一个二进制文件,并使用 struct 将每个元组编码为一个结构体。

from struct import Struct
def write_records(records, format, f):
    record_struct = Struct(format)
    for r in records:
        f.write(record_struct.pack(*r))

if __name__ == '__main__':
    records = [ (1, 2.3, 4.5),
                (6, 7.8, 9.0),
                (12, 13.4, 56.7) ]
    with open('data.b', 'wb') as f:
        write_records(records, '<idd', f)

读取这个文件中的内容:

  • 以块的形式增量读取文件
from struct import Struct

def read_records(format, f):
    record_struct = Struct(format)
    chunks = iter(lambda: f.read(record_struct.size), b'')
    return (record_struct.unpack(chunk) for chunk in chunks)

# Example
if __name__ == '__main__':
    with open('data.b','rb') as f:
        for rec in read_records('<idd', f):
  • 一次性读取到字符串中,分片解析
from struct import Struct

def unpack_records(format, data):
    record_struct = Struct(format)
    return (record_struct.unpack_from(data, offset)
            for offset in range(0, len(data), record_struct.size))

# Example
if __name__ == '__main__':
    with open('data.b', 'rb') as f:
        data = f.read()
    for rec in unpack_records('<idd', data):
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值