改善Python程序-字典+列表+集合

区别对待可变对象和不可变对象

数字、字符串、元组属于不可变对象,字典以及列表、字节数组属于可变对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Student(object):
def __init__(self,name,course=[]):
self.name=name
self.course=course
def addcourse(self,coursename):
self.course.append(coursename)
def printcourse (self):
for item in self.course:
print item
stuA=Student("Wang yi")
stuA.addcourse("English")
stuA.addcourse("Math")
print stuA.name +"s course: "
stuA.printcourse()
stuB=Student("Li san")
stuB.addcourse("Chinese")
stuB.addcourse("Physics")
print stuB.name +"s course:"
stuB.printcourse ()
Wang yis course:
English
Math
# Li san同学所选的多了 English和Math两门课程。
Li sans course:
English
Math
Chinese
Physics

由于init()函数的第二个参数是个默认参数,默认参数在函数被调用的时候仅仅被评估一次,以后都会使用第 一次评估的结果,因此实际上对象空间里面course所指向的是list的地址,每次操作的实际上是list所指向的具体列表。

1
2
3
4
5
def __init__(self,name,course=None):
self.name=name
if course is None:
course = []
self.course=course

对于可变对象,还有一个问题是需要注意的。

1
2
3
4
5
6
7
8
9
10
11
12
>>> listl = ('a', 'b','c')
>>> list2 = listl
>>> listl.append('d')
>>> listl
['a', 'b', 'c', 'd']
>>> list2
['a', 'b', 'c', 'd']
>>> list3 = listl [:]
>>> list3.remove ('a')
['b', 'c', 'd']
>>> list2
['a', 'b', 'c', 'd']

[],()和{}:一致的容器初始化形式

列表解析的语法为:[expr for iter item in iterable if cond expr]

1
2
3
4
5
6
7
8
9
10
11
12
# 1)支持多重嵌套
>>> nested_list = (['Hello', 'World'],['Goodbye','World']])
>>> nested_list = [ [s.upper()) for s in xs ] for xs in nested_list]
>>> print nested__list
[['HELLO','WORLD'],['GOODBYE','WORLD']]
# 2)支持多重迭代,下面的例子中a、b分别对应两个列表中的元素.
[(a,b) for a in ['a','1',1,2] for b in ['1',3,4,'b'] if a != b]
# 列表['a','1',1,2]和['1',3,4,'b']依次求笛卡儿积之后 并去掉元素值相等的元组之后所剩下的元组的集合
# 3)列表解析语法中的表达式可以是简单表达式,也可以是复杂表达式,其至是函数。
>>> [ v**2 if v%2 ==0 else v+1 for v in [2,3,4,-1] if v>0]

除了列表可以使用列表解析的语法之外,其他几种内罝的数据结构也支持

1
2
3
4
5
6
# 元组 (tuple)的初始化语法是
(expr for iter_item in iterable if cond_expr)
# 集合(set)的初始化语法是
{expr for iter_item in iterable if cond_expr}
# 字典(diet)也有类似的语法
{exprl,expr2 for iter_item in iterable if cond expr}

字典

字典迭代使用

1
2
for k,v in my_dict:
print "key:",k," value:",v

列表

使用enumerate()获取序列迭代的索引和值

1
2
3
4
5
6
7
8
9
10
li = ['a','b','c','d','e']
for i,e in enumerate(li):
print "index:",i,"element:",e
# enumerate内部实现
def enumerate(sequece,start=0):
n = start
for elem in sequece:
yield n, elem
n += 1

filter、map、reduce、lambda

lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边的返回值。lambda语句构建的其实是一个函数对象

1
2
3
4
g = lambda x : x**2
print g
<function <lambda> at 0x00AFAAF0>

filter(function, sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)返回:

1
2
3
>>> def f(x): return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

map(function, sequence) :对sequence中的item依次执行function(item),见执行结果组成一个List返回:

1
2
3
4
5
6
7
8
>>> def cube(x): return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
# 另外map也支持多个sequence,这就要求function也支持相应数量的参数输入:
>>> def add(x, y): return x+y
>>> map(add, range(8), range(8))
[0, 2, 4, 6, 8, 10, 12, 14]

reduce(function, sequence, starting_value):对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用,例如可以用来对List求和:

1
2
3
4
5
>>> def add(x,y): return x + y
>>> reduce(add, range(1, 11))
55 (注:1+2+3+4+5+6+7+8+9+10
>>> reduce(add, range(1, 11), 20)
75 (注:1+2+3+4+5+6+7+8+9+10+20