一、collections模块

在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:namedtuple、deque、Counter、OrderedDict和defaultdict等。

1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典

1、namedtuple

命名元组有助于对元组每个位置赋予意义,并且让我们的代码有更好的可读性和自文档性。
你可以在任何使用元组地方使用命名元组。
在例子中我们会创建一个命名元组以展示为元组每个位置保存信息。

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y']) # 定义命名元组
>>> p = Point(10, y=20) # 创建一个对象
>>> p
Point(x=10, y=20)
>>> p.x + p.y
30
>>> p[0] + p[1] # 像普通元组那样访问元素
30
>>> x, y = p # 元组拆封
>>> x
10
>>> y
20

类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:
namedtuple('名称', [属性list]):

Circle = namedtuple('Circle', ['x', 'y', 'r'])

2、deque

使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:

>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
>>> q.remove('a')
>>> q
deque(['y', 'b', 'c', 'x'])

deque除了实现list的append(),pop(),remove外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。

3、Counter
Counter 是一个有助于hashable对象计数的dict子类。它是一个无序的集合,目的是用来跟踪值出现的次数,其中hashable对象的元素存储为字典的键,它们的计数存储为字典的值,计数可以为任意整数,包括零和负数。

c = Counter('abcdeabcdabcaba')
print c
输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

Counter 示例
下面我们来看一个例子,例子中我们查看 Python 的 LICENSE 文件中某些单词出现的次数。

>>> from collections import Counter
>>> import re
>>> path = '/usr/lib/python3.4/LICENSE.txt'
>>> words = re.findall('\w+', open(path).read().lower())
>>> Counter(words).most_common(10)
[('the', 80), ('or', 78), ('', 66), ('of', 61), ('to', 50), ('and', 48), ('python', 46), ('in', 38), ('license', 37), ('any', 37)]

Counter 对象有一个叫做 elements() 的方法,其返回的序列中,依照计数重复元素相同次数,元素顺序是无序的。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['b','b','a', 'a', 'a', 'a']

most_common() 方法返回最常见的元素及其计数,顺序为最常见到最少。

>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]

4、OrderedDict

使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。(python3中dict的key已经默认是有序的了)
如果要保持Key的顺序,可以用OrderedDict:

>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是无序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序: >>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']

5、defaultdict

defaultdict 是内建 dict 类的子类,它覆写了一个方法并添加了一个可写的实例变量。其余功能与字典相同。
defaultdict() 第一个参数提供了 default_factory 属性的初始值,默认值为 None,default_factory 属性值将作为字典的默认数据类型。
所有剩余的参数与字典的构造方法相同,包括关键字参数。
同样的功能使用 defaultdict 比使用 dict.setdefault 方法快。

defaultdict 用例

>>> from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
dict_items([('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])])
在例子中你可以看到,即使 defaultdict 对象不存在某个键,它会自动创建一个空列表。

使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:

>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'

注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入。
除了在Key不存在时返回默认值,defaultdict的其他行为跟dict是完全一样的。

例子:

有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
即: {'k1': 大于66 , 'k2': 小于66}

l1 = [11,22,33,44,55,66,77,88,99,90]
result = {}
for i in l1:
if i>=66:
if 'k1' not in result:
result['k1'] = []
result['k1'].append(i)
else:
if 'k2' not in result:
result['k2'] = []
result['k2'].append(i) print(result)
# {'k2': [11, 22, 33, 44, 55], 'k1': [66, 77, 88, 99, 90]} 用defaultdict方法如下:
from collections import defaultdict
l1 = [11,22,33,44,55,66,77,88,99,90]
result = defaultdict(list)
for i in l1:
if i>=66:
result['k1'].append(i)
else:
result['k2'].append(i) print(result)
# defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55], 'k1': [66, 77, 88, 99, 90]}) for k in result:
print('{}:{}'.format(k, result[k]))
# k2:[11, 22, 33, 44, 55]
# k1:[66, 77, 88, 99, 90]

二、xml模块

1、xml介绍

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
现在这种格式的文件比较少了,但是还是存在的,所以大家简单了解一下,以备不时之需。

xml文件格式

<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>

2、对xml的增删改查简单操作(增删改查)

在进行操作之前,都应该进行这两步:

import xml.etree.ElementTree as ET
tree = ET.parse('a.xml') # 形成树形结构
root = tree.getroot() # 得到树的根系
print(root) # 循环打印:
for i in root:
print(i)
# <Element 'country' at 0x00000196B51191D8>
# <Element 'country' at 0x00000196B5124B88>
# <Element 'country' at 0x00000196B5124D18>

所有的增删改查都是基于这个root根系去操作

2.1、查 iter和findall:
1)、全文搜索 year 将所有的year标签全部找

print(root.iter('year'))
print([i for i in root.iter('year')])

2)、只找第一个,找到就返回

print(root.find('country'))

3)、在root的子节点找,找所有的

print(root.findall('country'))

练习

找到标签也可以找到标签相应的内容:tag,attrib,text

1)、找所有的rank标签,以及 attrib 和 text (这里利用列表推导式比较方便)
print([i for i in root.iter('rank')])
#[<Element 'rank' at 0x000001367D0D49F8>, <Element 'rank' at 0x000001367D0D4BD8>, <Element 'rank' at 0x000001367D0D4D68>]
print([i.attrib for i in root.iter('rank')])
#[{'updated': 'yes'}, {'updated': 'yes'}, {'updated': 'yes'}]
print([i.text for i in root.iter('rank')]) # ['2', '5', '69']
2)、找到第二个country的 neighbor标签以及他的属性
print([tag for tag in root.findall('country')][1].find('neighbor').attrib)
#{'direction': 'N', 'name': 'Malaysia'}

2.2、增 append

import xml.etree.ElementTree as ET
tree = ET.parse('a.xml') # 形成树形结构
root = tree.getroot() # 得到树的根系

给 year 大于2010年的所有标签下面添加一个month标签,属性为name:month 内容为30days

for country in root.findall('country'):
for year in country.findall('year'):
if int(year.text) > 2010:
month = ET.Element('month')
month.text = '30days'
month.attrib = {'name': 'month'}
country.append(month)
tree.write('b.xml')

2.3、改 set

import xml.etree.ElementTree as ET
tree = ET.parse('a.xml') # 形成树形结构
root = tree.getroot() # 得到树的根系
对所有的year属性以及值进行修改
for node in root.iter('year'):
new_year=int(node.text)+1
node.text=str(new_year)
node.set('updated','yes')
node.set('version','1.0')
tree.write('test.xml')

2.4、删 remove

import xml.etree.ElementTree as ET
tree = ET.parse('a.xml') # 形成树形结构
root = tree.getroot() # 得到树的根系 # 将 rank值大于50的country标签删除
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country) tree.write('output.xml')

3、自己创建xml文档

import xml.etree.ElementTree as ET

new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
age = ET.SubElement(name, "age", attrib={"checked": "no"})
sex = ET.SubElement(name, "sex")
sex.text = ''
name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age = ET.SubElement(name2, "age")
age.text = '' et = ET.ElementTree(new_xml) # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True) ET.dump(new_xml) # 打印生成的格式
 

day36-常见内置模块五(collections、xml模块)的更多相关文章

  1. 【python标准库模块五】Xml模块学习

    Xml模块 xml本身是一种格式规范,是一种包含了数据以及数据说明的文本格式规范.在json没有兴起之前各行各业进行数据交换的时候用的就是这个.目前在金融行业也在广泛在运用. 举个简单的例子,xml是 ...

  2. (十五)xml模块

    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要 ...

  3. 023--python os、sys、json、pickle、xml模块

    一.os模块 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 >>> os.getcwd() 'C:\\Python36' os.chdir(&quo ...

  4. Python第五章__模块介绍,常用内置模块

    Python第五章__模块介绍,常用内置模块 欢迎加入Linux_Python学习群  群号:478616847 目录: 模块与导入介绍 包的介绍 time &datetime模块 rando ...

  5. 简学Python第五章__模块介绍,常用内置模块

    Python第五章__模块介绍,常用内置模块 欢迎加入Linux_Python学习群  群号:478616847 目录: 模块与导入介绍 包的介绍 time &datetime模块 rando ...

  6. Python常用内置模块之xml模块

    xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.从结构上,很像HTML超文本标记语言.但他们被设计的目的是不同的,超文本标记语言被设计用来显示 ...

  7. oop、configparser、xml模块

    本节大纲:一:在python中,有两种编程思想.1:函数式编程.2:oop.无论是函数式编程还是oop都是相辅相成.并不是说oop比函数式编程就好.各有各的优缺点.在其他语言中java等只能以面向对象 ...

  8. s14 第5天 时间模块 随机模块 String模块 shutil模块(文件操作) 文件压缩(zipfile和tarfile)shelve模块 XML模块 ConfigParser配置文件操作模块 hashlib散列模块 Subprocess模块(调用shell) logging模块 正则表达式模块 r字符串和转译

    时间模块 time datatime time.clock(2.7) time.process_time(3.3) 测量处理器运算时间,不包括sleep时间 time.altzone 返回与UTC时间 ...

  9. python configparse模块&xml模块

    configparse模块 用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser. [DEFAULT] serveraliveinterval = ...

随机推荐

  1. 使用jquery.mCustomScrollbar自定义滚动条(2)

    参考博客:http://www.qianxingzhem.com/post-1602.html 接着上篇,另一个使用的例子,使用js来初始化滚动条,并且div中的内容可变化.需要调用相应的方法, 代码 ...

  2. Spring Boot 容器选择 Undertow 而不是 Tomcat

    Spring Boot 内嵌容器Undertow参数设置 配置项: # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 # 不要设置过大,如果过大,启动 ...

  3. [转][C#]BarCodeToHTML

    /// <summary> /// 类说明:Assistant /// 编 码 人:苏飞 /// 联系方式:361983679 /// 更新网站:http://www.sufeinet.c ...

  4. maven使用笔记--在父pom中声明过的jar可以被继承,使子项目不用写版本号由父pom控制

    将dependencies放到dependencyManagement中,如下: [html] view plaincopy <dependencyManagement> <depe ...

  5. Jmeter(二十七)Jmeter Question 之“集成Ant+Jenkins自动化”

    首先介绍一下Ant.Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发.由Apache软件基金会所提供. 是的.还是Apache家 ...

  6. 递归&栈帧空间

    递归函数: 自己调用自己的函数 def digui(n): print(n) if n > 0: digui(n-1) print(n) digui(5) 执行结果: 5 4 3 2 1 0 0 ...

  7. C#列的一些操作

    //变更列名 DataTableA.Columns["原来的列名"].ColumnName="新的列名";

  8. HBase核心知识点总结

    一.HBase介绍 1.基本概念 HBase是一种Hadoop数据库,经常被描述为一种稀疏的,分布式的,持久化的,多维有序映射,它基于行键.列键和时间戳建立索引,是一个可以随机访问的存储和检索数据的平 ...

  9. 实用JS代码

    浏览器功能 1.0 浏览器判断 如下代码判断是手机还是电脑访问的网站 function IsPC () { var userAgentInfo = navigator.userAgent var Ag ...

  10. System.Drawing.Graphics.FromImage(Image image)引发内存不足

    原因:图片位深度导致的,c# gui 应该无法将32位jpg格式的图片load到内存中 通过对比可成功处理的图片 和 不能处理的图片,发现 CMYK(印刷格式)的图片是无法处理的,具体需要深入 .ne ...