08 条件与循环,迭代器,列表解析,生成器(笔记)

来源:互联网 发布:手机淘宝店面 编辑:程序博客网 时间:2024/06/17 03:28

1. python采用缩进规则,可以有效避免dangling else

2. 条件表达式(三元操作符)t=x if condition1 else y

3. pass语句表示不做任何操作,即no operation

4. 对于一个很大范围的列表,xrange()比range()更适合,因为xrange()不会在内存中创建列表的完整拷贝


迭代器:

为类序列对象提供了一个类序列接口,可以遍历任何表示出序列行为的对象,比如字典key,文件行等。采用next()方法来遍历条目,结束后会抛出StopIteration一次,对于for循环方法,就是内部调用next()方法,并捕获异常。

- 序列

>>> s=[1,2,3]

>>> c=iter(s)

>>> c.next()

1

>>> c.next()

2

>>> c.next()

3

>>> c.next()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

StopIteration


for i in s: print i 实际是如下工作的,

>>> s

[1, 2, 3]

>>> while True:

...     try:

...             print i.next()

...     except StopIteration:

...             break

... 

1

2

3


- 字典
dict.iterkeys()
dict.itervalues()
dict.iteritems()

下面会返回一个独立于字典的列表,比较占内存
dict.items()
dict.keys()
dict.values()

dict.has_value()

>>> dic={"x":1,"y":2,"z":3}

>>> i=dic.iterkeys()

>>> i.next()

'y'

>>> i.next()

'x'

>>> i.next()

'z'

>>> i.next()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

StopIteration

>>> for i in dic:

...     print i

... 

y

x

z


- 文件
文件对象生成的迭代器会自动调用readline(),我们可以使用 for line in file来替换 for line in f.readlines(),当然有时候我们想要提高文件的使用效率,就是不已知占用文件,我们可以采用 file=open(path,mode); all=file.readlines(); file.close(); for line in all: operation(line),但是有没有发现如果是一个大的文件,利用readlines()太占用内存了,我们可以采用生成器,下面会提到。

迭代器也是有限制的,就是不能后退迭代,并且不能复制迭代器,如果想要再次迭代同个对象,就必须重新创建一个迭代器。对于可变对象,迭代过程中可以修改对象,但是对于不可变的对象,问题就会产生了,因为迭代器只记录你当前到达第几个元素,如果你在迭代时改变了元素,更新会立即反映到你所在的迭代条目上。如下例,dict的key是不可变的,使用keys()方法是可以的,因为keys()返回一个独立于字典的列表,而迭代器是与实际对象绑定在一起。

>>> dic

{'y': 2, 'x': 1, 'z': 3}

>>> for k in dic.keys():#返回独立列表

...     print k, dic[k]

...     del dic[k]

... 

y 2

x 1

z 3

>>> dic

{}


>>> l=[1,2,3]

>>> for i in l:

...     print i

...     l.remove(i)

... 

1

3

>>> l

[2]


>>> l=[1,2,3]

>>> i=iter(l)

>>> c=i.next()#指向index 0

>>> l.remove(c)

>>> i.next()    #指向index 1

3


>>> dic

{'y': 2, 'x': 1, 'z': 3}

>>> for k in dic:#与实体对象挂钩,iterator指向下一个key,而不是某个index,此时删除key,iterator根据不知道下一个该指向哪里

...     print k,dic[k]

...     del dic[k]

... 

y 2

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

RuntimeError: dictionary changed size during iteration

>>> dic

{'x': 1, 'z': 3}


列表解析:
[expr(x) for x in items if cond(x)]

- map, lambda, filter
map为每个元素执行某个操作,lambda允许快速创建一个只有一行的无名函数对象,filter可以过滤列表成员
1)map(lambda x: x**2, range(6))为range(6)列表成员指向lambda定义的函数操作,可用以下列表解析替换:
[x**2 for x in range(6)]
2)seq=[1,2,3,4,5];filter(lambda x: x%2, seq);等价于[x for x in seq if x%2]

例子:
- 矩阵

>>> [(x+1,y+1) for x in range(3) for y in range(5)]

[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5)]


- 文件
t.txt
I am watching the animation called The Adventure of Tintin.
It’s one of my most favorite cartoon during my childhood.
What about you? 

1)计算字符(包括空白)

>>> import os

>>> os.stat("t.txt").st_size

136

>>> sum([len(word) for line in open("t.txt","r") for word in line.split()])

113


2)计算有多少个字

>>> len([word for line in open("t.txt","r") for word in line.split()])

23


3)使游标返回文件开头
filehandle.seek(0)

- 输入值得总和

>>> sum([int(raw_input()) for i in range(5)])

1

2

3

4

5

15


生成器:列表解析会返回一个列表,对于大文件,显然太耗费内存了,而生成器可以直接返回一个值,并暂停函数的执行(yield)
生成器表达式:结合列表解析和生成器,内存更友好,lazy evaluation
(expr(x) for x in items if cond(x))

- 对于上面列表解析例子中的求文件中字符数(不包括空白)可以写为:

>>> sum(len(word) for line in open("t.txt","r") for word in line.split())

113

- 交叉配对

利用生成器的惰性分析,我们可以一个一个处理结果,此例中,我们采用输出处理

>>> l

[1, 2, 3]

>>> def cols():

...     yield 4

...     yield 5

...     yield 6

... 

>>> x=((i,j) for i in l for j in cols())

>>> x

<generator object <genexpr> at 0x1068bdcd0>

>>> for p in x:

...     print p

... 

(1, 4)

(1, 5)

(1, 6)

(2, 4)

(2, 5)

(2, 6)

(3, 4)

(3, 5)

(3, 6)


- 文件操作max(len(x.strip()) for x in open(path, mode)) 节省内存
=================================I am cute horizontal line=================================
练习题:

8-9:
def fibonacci(N):
"good example to recursive thought"
#the condition to stop 
if N<3:
return 1
#f(N)=f(N-1)+f(N-2), e.g. f(3)=f(1)+f(2), f(4)=f(3)+f(2), etc..
return fibonacci(N-1)+fibonacci(N-2)

8-11: 这个解答中只是简单的判断是否以“,”隔开姓和名,并且姓和名的第一个字母是否是大写的
def nameInput():
while True:
N=int(raw_input("Enter total number of names:"))
if N:
break
ls,count=[],0
for i in range(N):
s=raw_input("Please enter name %d: "%i)
if len(s.split(","))!=2 or s.split(",")[0].strip()[0].islower() or s.split(",")[1].strip()[0].islower():
count+=1
print "Wrong format... should be Last, First."
print "You have done this %d time(s) already. Fixing input..."%count
ls.append(s.replace(" ",",").lower().title())
else: ls.append(s.replace(" ",""))
print "sorted list (by last name) is:"
ls.sort()
for l in ls:
print l


Reference: 
1. Python核心编程 Ver3.0







0 0
原创粉丝点击