python核心编程--第八章

莫名其妙的就开始学习第八章了,我简单了看了下主题,发现这将是无聊的一章。

三元操作符被定义为: 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


转载于:https://my.oschina.net/voler/blog/138198

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值