python之3内置容器

所谓内置容器,就是不需要第三方模块,就可以使用的.


1.list容器,一个有序序列,类似于数组,但比数组强大很多
1.1.如何初始化list,直接一个[]即可,这是一个空的list
>>> li = []
>>> type(li)
<type 'list'>
>>> li = [1,2,3]
>>> li
[1, 2, 3]

1.2.如何使用list的元素,使用方法和数组一样
python之3内置容器len()可以统计list的长度
>>> li
[1, 2, 3]
>>> li[2]
3
>>> len(li)
3

1.3.如何确定list值是否存在,可以用in
in在list中有两种使用方法,第一种是作为关键字,遍历list的所有元素,第二种是作为二元操作运算符,判定某个值是否是list的元素.例如:
>>> for x in li:
    print x

   
1
2
3
>>> 4 in li
False

>>> 1 in li
True

1.4.del关键字,以下标为依据删除
>>> del li[2]
>>> li
[1, 2]

1.5.容器的方法函数
那么如何添加元素呢?这里可以用list的方法函数,我们可以用dir()来查看一个容器所包含的函数,如dir(li)
>>> dir(li)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

这里我们可以看到方法函数分两部分,分别是下划线开头和非下划线开头,下划线开头的一般是特殊作用函数,这里我们先不说,先说下非下划线开头的.

首先,要想添加一个元素,我们可以用append方法,append方法会将一个值追加到list的最后,例如:我们追加一个刚才删除的3

>>> li.append(3)
>>> li
[1, 2, 3]

添加多个元素,我们可以用extend方法
>>> li.extend([4,5,6])
>>> li
[1, 2, 3, 4, 5, 6]

但是如果直接追加一个迭代器函数,如range,那么追加进去的其实是一个元素[7,8,9,10]
>>> li.extend([range(7,11)])
>>> li
[1, 2, 3, 4, 5, 6, [7, 8, 9, 10]]

插入方法,insert(),格式是insert(下标位,元素)
>>> li.insert(0,0)
>>> li
[0, 1, 2, 3, 4, 5, 6]


删除方法1,remove(),格式是remove(元素),如有重复,则删除最小的下标元素
删除方法2,pop(),格式是pop(下标),删除对应下标的元素,并输出删除的元素值,pop本身含有取出的意思

统计方法,count(),格式是count(元素),统计某个元素的个数
搜索下标范围内元素位置,index(),格式是index(元素,起始下标,结束下标),如果范围内不存在,则报错,如果存在,则返回元素所在的最后一个位置(可能会有多个重复),例如:
>>> li
[0, 1, 2, 3, 4, 5, 6]
>>> li.index(3,0,2)

Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    li.index(3,0,2)
ValueError: 3 is not in list
>>> li.index(3,0,5)
3

排序方法,sort(),会将元素按照机器方法进行排序.例如将数字排列在一起,字符串排列在一起.
翻转方法,reverse(),会将元素位置反向排列,例如:
>>> li.reverse()
>>> li
[6, 5, 4, 3, 2, 1, 0]


1.6.切片,即获取某个范围下标内的元素,并不会修改原数组
格式:li[起始下标:结束下标:步进],步进的作用范围是起始和结束下标之间.
这里需要注意的是范围是不包含结束下标对应的元素的,如果下标是负数的话,则表示从右往左记数.例如:
>>> li = [1,2,3,4,5]
>>> type(li)
<type 'list'>
>>> li[2:4]
[3, 4]
>>> li[3:]
[4, 5]
>>> li[:3]
[1, 2, 3]
>>> li[:]
[1, 2, 3, 4, 5]
>>> li[0:-2]
[1, 2, 3]
>>> li[1:3:2]
[2]
#取得奇数
>>> li[::2]
[1, 3, 5]
#取得偶数
>>> li[1::2]
[2, 4]


2.元组tuple,支持list的所有功能,但是最大区别是元祖一旦定义好,不能修改,但是这个并不是一定的,如果元组本身的元素就是一个可变元素,那么这个元素是可以修改的.例如:
>>> t1 = ([1,2,3],['a','b','c'])
>>> type(t1)
<type 'tuple'>
>>> t1[0][0] = 100
>>> t1
([100, 2, 3], ['a', 'b', 'c'])

python之3内置容器定义单元素元组的时候,元素后面需要加逗号,如果不加则会定义成对应的元素类型,例如:
>>> a = (0)
>>> type(a)
<type 'int'>
>>> a = (0,)
>>> type(a)
<type 'tuple'>


3.集合set,关键符号{},set与list的最大区别是,元素没有重复,即使定义的时候重复,那么也会自动消除.
且,集合内的元素必须可hash,因为set需要依据元素的hash来判定是否重复.
又因为list不能被hash,所以list和包含list的容器都不能作为set的元素.例如:t1是一个包含list的元组,因此他不能被hash
>>> hash(t1)

Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    hash(t1)
TypeError: unhashable type: 'list'
>>> s1 = {t1}

Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    s1 = {t1}
TypeError: unhashable type: 'list'

另外,集合因为是无序的,故不能切片
3.1.集合set的方法和list有所不同,如下
3.1.1.
格式:集合名.方法名()
add()添加元素方法,类似于list的append()

update()添加迭代器元素,类似于list的extend()

remove()删除元素方法1,和list的一致
discard()删除元素方法2,和remove的区别在于,当元素不存在时,discard()不会报错
pop()删除元素方法3,和list的一致,会返回删除的元素
clear()删除元素方法4,清空所有元素

difference()差集计算,格式set1.difference(set2)=set1-set2,两者等价,例如
>>> s1 = {1,2,3}
>>> s2 = {2,3,4}
>>> s1.difference (s2)
set([1])
>>> s2.difference (s1)
set([4])


difference_update()差集计算,格式和difference一样,但是不同的是,他不会返回值,且会将源set改变为差集,即set1.difference.update(set2)=set1

intersection()交集计算,set1.intersection(set2)=set1 & set2
untion()并集计算,set1.untion(set2)=set1 | set2

symmetric_difference()两个集合相互差集的和
set1.symmetric_difference(set2)=(set1 - set2) | (set2 - set1)=set1 ^ set2

>>> s2.symmetric_difference (s1)
set([1, 4])
>>> 


isdisjoint()子集计算

4.list,tuple,set之间的转换
list(),tuple(),set()函数可以实现
>>> s1
set([1, 2, 3])
>>> tuple(s1)
(1, 2, 3)
>>> list(s1)
[1, 2, 3]


一个利用转换实现list元素去重的例子:先利用set将
>>> li1=[1,1,2,2,3,3]
>>> li1=list(set(li1))
>>> li1
[1, 2, 3]



5.迭代器
5.1.
iter()迭代器,可以将一个list构建成一个迭代器,且可以用next方法以每次递增一个下标位来输出元素,直至输出完毕得到StopIteration,例如:
>>> li2=[1,2,3,4]
>>> li2=iter (li2)
>>> li2.next()
1
>>> li2.next()
2
>>> li2.next()
3
>>> li2.next()
4
>>> li2.next()

Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    li2.next()
StopIteration

python之3内置容器for语句就是对next方法的调用,当捕获到StopIteration错误的时候,就停止了

6.字典dict
字典使用{}进行初始化,和集合一样
字典的元素由两部分组成,key:value
key必须可hash,且不能重复,但是字典自身不能hash
例如:定义一个字典dict

>>> d1 = {}
>>> type (d1)
<type 'dict'>
>>> d1 = {'d2':2,'d1':1}
>>> d1
{'d2': 2, 'd1': 1}
>>> type (d1)
<type 'dict'>


dict的方法可以分为三类,一类针对key,一类针对value,最后一类同时针对key和value,即item
每一类都有对应的三种方法
key对应的是keys(),iterkeys(),viewkeys()
value对应的是values(),itervalues(),viewvalues()
tiem对应的是items(),iteritems(),viewitems()
以dict.key为例:

keys方法可以输出dict的所有元素的keys
>>> d1.keys()
['d2', 'd1']


iterkeys方法可以将dict的所有元素的keys生成迭代器
>>> it = d1.iterkeys()
>>> it.next()
'd2'
>>> it.next()
'd1'

viewkeys可以返回一个dict的keys对象
>>> d1.viewkeys()
dict_keys(['d2', 'd1'])


以item来说,则是(key,value)元组堆,例如:
>>> d1.items()
[('d2', 2), ('d1', 1)]


>>> it1=d1.iteritems()
>>> it1.next()
('d2', 2)


>>> v11=d1.viewitems()
>>> v11
dict_items([('d2', 2), ('d1', 1)])



一个for循环的例子:
"%s" -- %(变量)

>>> for k,v in d1.items():
    print "%s => %s" %(k,v)

   
d2 => 2
d1 => 1


6.2.字典的操作
6.2.1.判定字典内是否有key,有两种方法,第一种方法是has_key(),第二种方法是get()
对于第一种方法has_key(),如果有,则返回true,否则返回false,例如:
>>> d1
{'d2': 2, 'd1': 1}
>>> d1.has_key('d3')
False
>>> d1.has_key('d1')
True

对于第二种方法get(),如果有,则返回值,如果没有则返回none,但是并不输出出来,例如:
>>> d1.get('d1')
1
>>> g1=d1.get('d3')
>>> print g1
None

不过,当key不存在,又想要赋予一个值,可以这么写,例如:
>>> d1.get('d3','false')
'false'


6.2.2.
pop方法,删除指定的key,并补充对应key的value为none(若默认值不存在)
格式:字典名.pop(key,默认值)

6.2.3.
添加/修改单个字典元素
格式:字典名['key']=value
>>> d1['d3']=3
>>> d1
{'d2': 2, 'd3': 3, 'd1': 1}

添加/修改多个字典元素
>>> d1.update({'d4':4,'d5':5})
>>> d1
{'d4': 4, 'd5': 5, 'd2': 2, 'd3': 3, 'd1': 1}

或者以下写法,不过这种写法,key不能是纯数字
>>> d1.update(d5=5,d6=6)
>>> d1
{'d5': 5, 'd6': 6, 'd4': 4, 'd5': 5, 'd2': 2, 'd3': 3, 'd1': 1}


6.2.4.复制
可以使用copy()方法,这里不能直接使用赋值运算符,在字典中,直接赋值运算符其实只是一个指针指向原字典.
>>> d1
{'d6': 6, 'd4': 4, 'd5': 5, 'd2': 2, 'd3': 3, 'd1': 1}
>>> type(d1)
<type 'dict'>
>>> d2=d1.copy()
>>> d2
{'d6': 6, 'd4': 4, 'd5': 5, 'd2': 2, 'd3': 3, 'd1': 1}


7.列表解析
7.1.最基本的列表解析
返回列表

格式:[expr for item in iterator]
expr表达式可以包含item变量

例如:
>>> l1=[1,2,3,4,5]
>>> [x for x in l1]
[1, 2, 3, 4, 5]
>>> [x+1 for x in l1]
[2, 3, 4, 5, 6]


7.2返回迭代器
迭代器解析和列表一样,只不过使用()包裹,而不是[]
格式:(expr for item in iterator)
例如:
>>> l1=[1,2,3,4,5]
>>> i1=(x+1 for x in l1)
>>> i1
<generator object <genexpr> at 0x029D29E0>
>>> i1.next()
2
>>> i1.next()
3
>>> i1.next()
4
>>> i1.next()
5
>>> i1.next()
6
>>> i1.next()

Traceback (most recent call last):
  File "<pyshell#134>", line 1, in <module>
    i1.next()
StopIteration

python之3内置容器列表和迭代器的区别就在于,迭代器的输出是可控制的

7.3.带条件的列表解析
格式:[expr for item in iterator if condition1 if condition2]
expr和condition均可以使用item
例如:获取列表的所有偶数
>>> [x for x in l1 if x%2==0]
[2, 4]


7.4.笛卡尔积(集合1的元素与集合2的元素相互组合)
格式:[expr for item1 in iterator1 for item2 in iterator2 ]
等价于:
ret=[]
for item1 in iterator1:
    for item2 in iterator2:
        ret.append(expr)
例子:
>>> l1=[1,2]
>>> l2=[3,4]
>>> [(x,y) for x in l1 for y in l2]
[(1, 3), (1, 4), (2, 3), (2, 4)]
>>> [x*y for x in l1 for y in l2]
[3, 4, 6, 8]


等价于
l1=[1,2]
l2=[3,4]
ret=[]
for x in l1:
    for y in l2:
        ret.append(x*y)


7.5.使用列表解析的好处
简洁;速度;符合python的原则,即有且只有一个最优方式

8.练习
8.1.打印杨辉三角
#!/usr/bin/env python
# encoding:utf-8
#定义第一行列表
li = [1]
#定义总行号
num1 = int(raw_input("请输入行号:"))
#开始循环,row表示每次循环时的行号
for row in range(num1):
#输出每行前的空格,K表示每次输出的个数
    for K in range(num1-1):
        print ' ',
    num1 = num1-1
#输出上次循环所获的行数据,n表示每行的各个元素
    for n in iter(li):
        print "%s  " %n,
#打印每行末的换行符
    print
#获取本次循环所得到的行数据,并更新li列表,便于下次循环前输出,zip()函数可以将两个列表,重组成[(x,y)]形式的列表.临时列表a>的目的是为了交错相加,实现杨辉三角的定律,构建下一行列表
    a = [0]
    a.extend(li)
    li.append(0)
    li=[x+y for x,y in zip(a,li)]

[root@bogon ~]# python test4.py 
请输入行号:6
          1  
        1   1  
      1   2   1  
    1   3   3   1  
  1   4   6   4   1  
1   5   10   10   5   1  

python之3内置容器
在交互式输入的时候,建议使用raw_input,而不是input.
来源: <http://www.cnblogs.com/way_testlife/archive/2011/03/29/1999283.html>

 
解析:杨辉三角的每一行的数字均由对应的上一行两个数字相加组成.
因此,加入要想获得某行的数字,则将上一行数字错位相加即可
例如,第五行是[1,4,6,4,1],第四行是[1,3,3,1],那么[0,1,3,3,1]与[1,3,3,1,0]对应数字相加,就是[1,4,6,4,1]
所以,我们利用在上一行的下标0和下标n分别加入[0],组成两个新的列表,然后两个列表对应下标相加,即可得出下一行.
python之3内置容器关于添加[0]元素这个,不建议用+号直接添加,即[0]+li,li+[0],因为如此以来,会返回两个新的列表,占用额外内存.
那么首先,我们怎么计算呢?
可以用zip函数,zip函数可以将两个列表对应下标元素进行组合,构成元组(x,y)为元素的新列表.
上一篇:ENode 1.0 - 整体架构介绍


下一篇:Android Fragment 真正的完全解析(下)