莫名其妙的就开始学习第八章了,我简单了看了下主题,发现这将是无聊的一章。
三元操作符被定义为: X if C else Y
8.11 迭代器和iter()函数
迭代器:为类序列对象提供一个类序列的接口
8.11.2 为什么要迭代器
提供了可扩展的迭代器接口
对列表迭代带来了性能上的增强
在字典迭代中性能提升
创建真正的迭代接口,而不是原来的随机对象访问
与所有已经存在的用户定义的类似及扩展到模拟序列和映射到对象向后兼容
迭代非序列集合时,可以创建更简洁可读的代码
8.11.3 如何迭代
根本上说,迭代器就是有一个next()方法的对象,而不是通过索引来计数。一个循环机制(如for循环)需要下一项时,调用迭代器的next()方法就可以获得它。条目全部取出后,会引发一个StopIteration异常,这并不表示错误发生,只是告诉外部调用者,迭代完成。
不过,迭代器也有一些限制。例如你不能向后移动,不能回到开始,也不能复制一个迭代器。如果你要再次迭代同个对象,你只能去创建另一个迭代器对象。
8.11.4 使用迭代器
序列
>>> myTuple = (1,2,3)
>>> myTuple
(1, 2, 3)
>>> i = iter(myTuple)
>>> i.next()
1
>>> i.next()
2
>>> i.next()
3
>>> i.next()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
i.next()
StopIteration
for循环实际上就是一个迭代。
for i in seq:
do_something_to(i)
等价于:
fetch = iter(seq)
while True:
try:
i = fecth.next()
except StopIteration:
break
do_something_to(i)
>>> dict1 = {}
>>> dict1[1] = "hello"
>>> dict1[2] = "world"
>>> dict1[3] = "i"
>>> for key in dict1.iterkeys():
print key
1
2
3
>>> for value in dict1.itervalues():
print value,
hello world i
>>> for item in dict1.iteritems():
print item,
(1, 'hello') (2, 'world') (3, 'i')
>>> myFile = open("data.txt")
>>> for eachline in myFile:
print eachline
一个人默默的在办公室里学习的,也是感到挺烦的其实。
不过也明白自己的责任
好好学习吧
8.11.5 可变对象和迭代器
记住!!!在迭代可变对象的时候修改他们并不是个好主意!!!!
8.11.6 如何创建迭代器
对一个对象调用iter()就可以得到它的迭代器。
iter(obj)
iter(func, sentinel)
对于两个参数给iter(),它会重复调用func,直到迭代器的下个值等于sentinel
8.12 列表解析
其实我觉得lambda更拉风点
【expr for iter_var in iterable】
列表解析的语法,它迭代iterable对象的所有条目。
>>> [x ** 2 for x in range(6)]
[0, 1, 4, 9, 16, 25]
【expr for iter_var in iterable if cond_expr】
增加了if的判断
>>> seq = [1,2,3,4,5,6,7,8,9]
>>> [x for x in seq if x % 2]
[1, 3, 5, 7, 9]
也可以用于矩阵:
>>> [(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)]
也可以用于磁盘文件:
假设我们需要计算出所有非空白字符的数目:
>>> f = open("data.txt")
>>> len([word for line in f for word in line.split(" ")])
3
也可快速的计算出文件大小:
>>> import os
>>> os.stat("data.txt").st_size
84L
>>> f.seek(0)
>>> sum([len(word) for line in f for word in line.split(" ")])
82
8.13 生成器表达式
列表解析的一个不足就是必要生成所有的数据,用以创建整个列表。这可能对有大量数据的迭代器有负面效应。生成器表达式通过结合列表解析和生成器解决了这个问题。
生成器表达式:
(expr for iter_var in iterable if cond_expr)
生成器并不会让列表解析废弃,它只是一个内存使用更友好的结构。
举个例子用来表达生成器的妙用。读取一个文件最长行的长度:
用生成器的话,一行代码:
>>> max(len(x.strip()) for x in open("data.txt"))
18
可能有人说,我可以用列表解析啊:
>>> max([len(x.strip()) for x in open("data.txt")])
18
但是,列表解析读取了所有的文件进内存,而生成器没有,它只是保留着信息。
忽然之间,又到了练习。
中午时候,感到特别的累,回去睡了一觉。感觉一个人一定要懂得休息。身体是革命的本钱。
练习8.15
8–2. 循环. 编写一个程序, 让用户输入三个数字: (f)rom, (t)o, 和 (i)ncrement . 以 i为步长, 从 f 计数到 t , 包括 f 和 t . 例如, 如果输入的是 f == 2, t == 26, i == 4 , 程序将输出 2, 6, 10, 14, 18, 22, 26.
if __name__ == "__main__":
strTemp = raw_input("please enter three number(like 1,2,3 ):")
num = strTemp.split(",")
for i in range(int(num[0]), int(num[1]) + 1, int(num[2])):
print i,
程序输出:
>>>
please enter three number(like 1,2,3 ):2,26,4
2 6 10 14 18 22 26
8–3. range() . 如果我们需要生成下面的这些列表, 分别需要在 range() 内建函数中提
供那些参数?
(a) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
(b) [3, 6, 9, 12, 15, 18]
(c) [-20, 200, 420, 640, 860]
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(3, 19, 3)
[3, 6, 9, 12, 15, 18]
>>> range(-20, 861, 220)
[-20, 200, 420, 640, 860]
8–4. 素数. 我们在本章已经给出了一些代码来确定一个数字的最大约数或者它是否是一个素数. 请把相关代码转换为一个返回值为布尔值的函数,函数名为 isprime() . 如果输入的是一个素数, 那么返回 True , 否则返回 False .
def isprime(num):
item = set(range(2, num / 2 + 1))
while item:
oneNum = item.pop()
if num % oneNum == 0:
return False
else:
item &= set(x for x in item if (x % oneNum != 0) or (oneNum % x != 0))
return True
if __name__ == "__main__":
while True:
num = raw_input("please enter one number(q to quit):")
if num.lower() == "q":
break
if isprime(int(num)):
print "number %s is prime" % num
else:
print "number %s is not prime" % num
程序输出:
>>>
please enter one number(q to quit):11
number 11 is prime
please enter one number(q to quit):9
number 9 is not prime
please enter one number(q to quit):123
number 123 is not prime
please enter one number(q to quit):667
number 667 is not prime
please enter one number(q to quit):561
number 561 is not prime
please enter one number(q to quit):9999
number 9999 is not prime
please enter one number(q to quit):99999
number 99999 is not prime
please enter one number(q to quit):161
number 161 is not prime
please enter one number(q to quit):199
number 199 is prime
please enter one number(q to quit):q
8–5. 约数. 完成一个名为 getfactors() 的函数. 它接受一个整数作为参数, 返回它所有约数的列表, 包括 1 和它本身,
def getfactors(num):
set1 = set()
set1.add(1)
set1.add(num)
i = 2
while num >= i:
if num % i == 0:
set1.add(i)
i += 1
return set1
if __name__ == "__main__":
while True:
num = raw_input("please enter the num(q to qiut):")
if num.lower() == "q":
break
print getfactors(int(num))
程序输入输出:
>>>
please enter the num(q to qiut):16
set([16, 1, 2, 4, 8])
please enter the num(q to qiut):30
set([1, 2, 3, 5, 6, 10, 15, 30])
please enter the num(q to qiut):11
set([1, 11])
please enter the num(q to qiut):q
8–6. 素因子分解. 以刚才练习中的 isprime() 和 getfactors() 函数为基础编写一个函数, 它接受一个整数作为参数, 返回该整数所有素数因子的列表. 这个过程叫做求素因子分解, 它输出的所有因子之积应该是原来的数字. 注意列表里可能有重复的元素. 例如输入 20 , 返回结果应该是 [2, 2, 5] .
def getfactors(num):
numLst = []
numLst.append(1)
numLst.append(num)
i = 2
while num >= i:
if num % i == 0:
numLst.append(i)
num /= i
else:
i += 1
return numLst
def isprime(num):
if num == 1:
return False
item = set(range(2, num / 2 + 1))
while item:
oneNum = item.pop()
if num % oneNum == 0:
return False
else:
item &= set(x for x in item if (x % oneNum != 0) or (oneNum % x != 0))
return True
if __name__ == "__main__":
while True:
num = raw_input("please enter the num(q to qiut):")
if num.lower() == "q":
break
print [x for x in getfactors(int(num)) if isprime(int(x))]
程序输出:
>>>
please enter the num(q to qiut):20
[2, 2, 5]
please enter the num(q to qiut):30
[2, 3, 5]
please enter the num(q to qiut):121
[11, 11]
please enter the num(q to qiut):q
这里对getfactors进行了修改,用来符合此题的要求
8–7. 全数. 完全数被定义为这样的数字: 它的约数(不包括它自己)之和为它本身. 例如: 6的约数是 1, 2, 3, 因为 1 + 2 + 3 = 6 , 所以 6 被认为是一个完全数. 编写一个名为 isperfect()的函数, 它接受一个整数作为参数, 如果这个数字是完全数, 返回 1 ; 否则返回 0 .
def getfactors(num):
numLst = []
numLst.append(1)
i = 2
while num >= i:
if num % i == 0:
numLst.append(i)
num /= i
else:
i += 1
return numLst
if __name__ == "__main__":
while True:
num = raw_input("please enter the num(q to qiut):")
if num.lower() == "q":
break
if sum(getfactors(int(num))) == int(num):
print "这是个完全数"
else:
print "这不是一个完全数"
程序输入输出:
>>>
please enter the num(q to qiut):6
这是个完全数
please enter the num(q to qiut):7
这不是一个完全数
please enter the num(q to qiut):8
这不是一个完全数
please enter the num(q to qiut):q
8–8. 阶乘. 一个数的阶乘被定义为从 1 到该数字所有数字的乘积. N 的阶乘简写为 N! .写一个函数, 指定N, 返回 N! 的值.
def fac(num):
if num == 1:
return 1
else:
return num * fac(num - 1)
程序输入输出:
>>> fac(4)
24
>>> fac(5)
120
8–9. Fibonacci 数列. Fibonacci 数列形如 1, 1, 2, 3, 5, 8, 13, 21, 等等. 也就是说,下一个值是序列中前两个值之和. 写一个函数, 给定 N , 返回第 N 个 Fibonacci 数字. 例如, 第1 个 Fibonacci 数字是 1 , 第 6 个是 8 .
def fib(num):
a,b = 1,1
while num - 1:
a,b = b,a + b
num -= 1
return a
程序输入输出:
>>> fib(5)
5
>>> fib(8)
21
8–11. 文本处理. 要求输入一个姓名列表,输入格式是“Last Name, First Name,” 即 姓,逗号, 名. 编写程序处理输入, 如果用户输入错误, 比如“First Name Last Name,” , 请纠正这些错误, 并通知用户. 同时你还需要记录输入错误次数. 当用户输入结束后, 给列表排序, 然后以"姓 , 名" 的顺序显示.
num = []
count = 0
while True:
name = raw_input("please enter the name like(last name, first name)(q to quit):")
if name.lower() == "q":
for item in num:
print item
break
if name.find(",") == -1:
count += 1
print "wront time %d" % count
num.append([name.split(" ")])
else:
num.append([name.split(",")])
程序输出:
>>>
please enter the name like(last name, first name)(q to quit):smith, joe
please enter the name like(last name, first name)(q to quit):mary wong
wront time 1
please enter the name like(last name, first name)(q to quit):royce,linda
please enter the name like(last name, first name)(q to quit):winston salem
wront time 2
please enter the name like(last name, first name)(q to quit):q
[['smith', ' joe']]
[['mary', 'wong']]
[['royce', 'linda']]
[['winston', 'salem']]
8–12. (整数)位操作. 编写一个程序, 用户给出起始和结束数字后给出一个下面这样的表格,分别显示出两个数字间所有整数的十进制, 二进制, 八进制和十六进制表示. 如果字符是可打印的ASCII 字符, 也要把它打印出来, 如果没有一个是可打印字符, 就省略掉 ASCII 那一栏的表头.
while True:
print "-" * 10
beginValue = raw_input("enter begin value(q to quit):")
if beginValue.lower() == "q":
break
endValue = raw_input("enter end value(q to quit):")
if endValue.lower() == "q":
break
if (int(beginValue) >= 33 and int(beginValue) <= 126) or (int(endValue) >= 33 and int(endValue) <= 126):
print "DEC BIN OCT HEX ASCII"
print "-" * 50
for i in range(int(beginValue), int(endValue) + 1):
print "%-10d%-10s%-10o%-10x%-10s" % (i, bin(i), i, i, chr(i))
else:
print"DEC BIN OCT HEX "
print "-" * 40
for i in range(int(beginValue), int(endValue) + 1):
print "%-10d%-10s%-10o%-10x" % (i, bin(i), i, i)
程序输入输出:
>>>
----------
enter begin value(q to quit):9
enter end value(q to quit):18
DEC BIN OCT HEX
----------------------------------------
9 0b1001 11 9
10 0b1010 12 a
11 0b1011 13 b
12 0b1100 14 c
13 0b1101 15 d
14 0b1110 16 e
15 0b1111 17 f
16 0b10000 20 10
17 0b10001 21 11
18 0b10010 22 12
----------
enter begin value(q to quit):26
enter end value(q to quit):41
DEC BIN OCT HEX ASCII
--------------------------------------------------
26 0b11010 32 1a
27 0b11011 33 1b
28 0b11100 34 1c
29 0b11101 35 1d
30 0b11110 36 1e
31 0b11111 37 1f
32 0b100000 40 20
33 0b100001 41 21 !
34 0b100010 42 22 "
35 0b100011 43 23 #
36 0b100100 44 24 $
37 0b100101 45 25 %
38 0b100110 46 26 &
39 0b100111 47 27 '
40 0b101000 50 28 (
41 0b101001 51 29 )
----------
enter begin value(q to quit):q