[PYTHON] 核心编程笔记之八-Py

发布时间:2019-07-11 09:49:43编辑:auto阅读(1327)

    8.1 if语句


    if expression:

       expr_true_suite


    8.1.1 多重条件表达式

    单个if 语句可以通过使用and,or和not实现多重判断条件或是否定判断条件


    if not warn and (system_load>=10):

       print "WARNING: losing resources"

       warn +=1


    8.1.2 单一语句的代码块


    if make_hard_copy: send_data_to_printer()


    8.2 else 语句

    if expression:

       expr_true_suite

    else:

       expr_false_suite


    8.2.1 避免"悬挂else"


    8.3 elif(即else-if)语句

    if expression1:

       expr1_true_suite

    elif expression2:

       expr2_true_suite

    elif expressionN:

       expeN_true_suite

    else:

       none_of_the_above_suite


    8.4 条件表达式(即"三元操作符")

    >>> x, y=4, 3    

    >>> if x < y:    

    ...   smaller = x

    ... else:        

    ...   smaller = y

    ...

    >>> smaller

    3

    >>> smaller = (x < y and [x] or [y])[0]

    >>> smaller

    3

    >>> smaller = x if x < y else y

    >>> smaller

    3


    8.5 while 语句

    8.5.1 一般语法

    while 循环的语法如下:


    while expression:

       suite_to_repeat

    while循环的suite_to_repeat子句会一直循环下去,直到expression值为假


    8.5.2 技术循环

    >>> count = 0        

    >>> while (count < 9):

    ...   print 'the index is:',count

    ...   count +=1

    ...

    the index is: 0

    the index is: 1

    the index is: 2

    the index is: 3

    the index is: 4

    the index is: 5

    the index is: 6

    the index is: 7

    the index is: 8


    8.5.3 无限循环

    while True:

       handle,indata = wait_for_client_connect()

       outdata = process_request(indata)

       ack_result_to_client(handle,outdata)

    注: 以上代码为无限循环,因为服务器代码是用来等待客户端(可能通过网络)来连接的,这些客户端向服务器发送请求,服务器处理请求,请求被处理,服务器向客户端返回数据


    8.6 for 语句

    8.6.1 一般语法:

    for iter_var in iterable:

       suite_to_repeat

    每次循环,lter_var迭代变量被设置为可迭代对象的当前元素,提供给suite_to_repeat语句块使用


    8.6.2 用于序列类型

    >>> for eachLetter in 'Names':

    ...     print 'current letters',eachLetter

    ...

    current letters N

    current letters a

    current letters m

    current letters e

    current letters s


    通过序列项迭代

    >>> nameList = ['Walter',"Nicole",'Steven','Henry']

    >>> for eachName in nameList:

    ...     print eachName,"Lim"

    ...

    Walter Lim

    Nicole Lim

    Steven Lim

    Henry Lim


    通过序列索引迭代

    >>> nameList = ['Cathy',"Terry","Joe",'heather','Lucy']

    >>> for nameIndex in range(len(nameList)):            

    ...   print "Liu",nameList[nameIndex]                  

    ...

    Liu Cathy

    Liu Terry

    Liu Joe

    Liu heather

    Liu Lucy


    >>> len(nameList)

    5

    >>> range(len(nameList))

    [0, 1, 2, 3, 4]


    使用range()我们可以得到用来迭代nameList的索引数列表:使用切片/下标操作符([]),就可以访问对应的序列对象


    使用项和索引迭代

    使用enumerate()函数

    >>> nameList = ['Donn','Shirley','Ben','Janice','David','Yen','Wendy']

    >>> for i,eachLee in enumerate(nameList):

    ...   print "%d %s Lee" %(i+1,eachLee)

    ...

    1 Donn Lee

    2 Shirley Lee

    3 Ben Lee

    4 Janice Lee

    5 David Lee

    6 Yen Lee

    7 Wendy Lee


    8.6.3 用于迭代器类型

    用for循环访问迭代器和访问序列的方法差不多,区别是for语句会做一些额外的事情

    迭代器对象有一个next()方法,调用后返回下一条目,所有条目迭代完,迭代器引发一个StopIteration一场告诉程序循环结束,for语句在内部调用next()病捕获异常


    8.6.4 range()内建函数:

    range(start, end, step = 1)

    range()会返回一个包含所有k的列表,这里start<=k<end, 从start到end, k每次递增step, step不可以为零,否则将发生错误

    >>> range(2,19,3)

    [2, 5, 8, 11, 14, 17]


    只给定两个参数,省略step,step就使用默认1

    >>> range(3,7)

    [3, 4, 5, 6]


    例:

    >>> for eachVal in range(2,19,3):

    ...    print "value is: ",eachVal

    ...

    value is:  2

    value is:  5

    value is:  8

    value is:  11

    value is:  14

    value is:  17


    range()简略语法:


    range(end)

    range(start,end)


    >>> range(5)

    [0, 1, 2, 3, 4]


    >>> for count in range(2,5):

    ...   print count

    ...

    2

    3

    4


    注:

    >>> range(start=0,end,step=1)  

     File "<stdin>", line 1

    SyntaxError: non-keyword arg after keyword arg


    这个语法不可以使用两个参数调用,因为step要求给定start


    8.6.5 xrange()内建函数:

    8.6.6 与序列相关的内建函数:

    sorted(),reversed(),enumerate(),zip()


    >>> albums = ('Poe','Gaudi','Freud','Poe2')

    >>> years = (1976,1987,1990,2003)

    >>> for album in sorted(albums):

    ...     print album,

    ...

    Freud Gaudi Poe Poe2

    >>> for album in reversed(albums):

    ...     print album,              

    ...

    Poe2 Freud Gaudi Poe

    >>> for i,album in enumerate(albums):

    ...     print i,album

    ...

    0 Poe

    1 Gaudi

    2 Freud

    3 Poe2

    >>> for album,yr in zip(albums,years):

    ...     print yr, album

    ...

    1976 Poe

    1987 Gaudi

    1990 Freud

    2003 Poe2


    8.7 break语句

    break语句可以结束当前循环然后跳转到下条语句,常用于while和for循环

    count = num / 2

    while count > 0:

       if num % count == 0:

    print count, 'is the largest factor of', num

    break

       count -= 1


    8.8 continue 语句

    continue在开始下一次循环前需要满足一些先决条件,否则循环会正常结束,常用在while和for循环里

    #!/usr/bin/env python

    valid = False

    count = 3

    while count > 0:

       input = raw_input("enter password")

       for eachPasswd in passwdList:

           if input == eachPasswd:

               valid = True

               break

           if not valid:

               print "invalid input"

               count -= 1

               continue

           else:

               break


    8.9 pass语句


    def foo_func():

       pass

    或是


    if user_choice = 'do_calc':

       pass else:

       pass


    这样的代码结构在开发和调试时很有用,因为编写代码的时候你可能要先把结构定下来,但你不希望它干扰其他已经完成的代码,在不需要它做任何事情的地方,放一个pass将是一个很好的主意


    8.10 再谈else语句

    Python可以在while和for循环中使用else语句,在循环使用时,else子句只在循环完成后执行,也就是break会跳过else块


    例:

    -------------------------

    #!/usr/bin/env python

    def showMaxFactor(num):

       count = num / 2

       while count > 1:

           if num % count ==0:

               print 'largest factor of %d is %d' %(num,count)

               break

           count -= 1

       else:

           print num, "is prime"


    for eachNum in range(10,21):

       showMaxFactor(eachNum)

    --------------------------

    showMaxFactor()函数中第3行的循环从amount的一般开始计数(这样就可以检查这个数是否能被2整除,如果可以,那就找到了最大约数),然后循环每次递减1,直到发现约数,如果循环递减到1还没有找到约束,那么这个数一定是素数,11-12行的else子句负责处理这样的情况


    largest factor of 10 is 5

    11 is prime

    largest factor of 12 is 6

    13 is prime

    largest factor of 14 is 7

    largest factor of 15 is 5

    largest factor of 16 is 8

    17 is prime

    largest factor of 18 is 9

    19 is prime

    largest factor of 20 is 10


    for与while处理方式相同,只要for循环为正常结束,else子句就会执行


    条件与循环语句对照表


    ifwhilefor

    elif*

    else***

    break**

    continue**

    pass***

    8.11 迭代器和iter()函数:


    8.11.1 什么是迭代器?

    8.11.2 为什么要迭代器?

    8.11.3 如何迭代?

    next() reversed() enumerate() any() all()方法


    8.11.4 使用迭代器

    例:

    >>> myTuple = (123, 'xyz', 45,67)

    >>> i = iter(myTuple)

    >>> i.next()

    123

    >>> i.next()

    'xyz'

    >>> i.next()

    45

    >>> i.next()

    67

    >>> i.next()

    Traceback (most recent call last):

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

    StopIteration


    如果这是一个实际应用程序,那么我们需要把代码放在一个try-except块中,序列现在会自动的产生他们自己的迭代器,所以一个for循环:

    for i in seq:

       do_something_to(i)

    ------------------------------

    fetch = iter(seq)

    while True:

       try:

    i = fetch.next()

       except StopIteration:

    break

    do_something_to(i)


    字典

    语句for eachKey in myDict.keys()可以缩写为for eachKey in myDict


    >>> legends = {('Poe', 'author'):(1809, 1849, 1976),('Gaudi','architect'):(1852,1906,1987),('Freud','psychoanalyst'):(1856,1939,1990)}

    >>> for eachLegend in legends:

    ...     print 'Name: %s \t Occupation: %s' % eachLegend

    ...     print 'Birth:%s\tDeath: %s\tAlbum: %s\n' %legends[eachLegend]

    ...


    Name: Poe        Occupation: author

    Birth:1809      Death: 1849     Album: 1976


    Name: Gaudi      Occupation: architect

    Birth:1852      Death: 1906     Album: 1987


    Name: Freud      Occupation: psychoanalyst

    Birth:1856      Death: 1939     Album: 1990

    Name: Poe        Occupation: author

    Birth:1809      Death: 1849     Album: 1976


    Name: Gaudi      Occupation: architect

    Birth:1852      Death: 1906     Album: 1987


    Name: Freud      Occupation: psychoanalyst

    Birth:1856      Death: 1939     Album: 1990


    另外:python还引进了三个新的内建字典方法来定义迭代:myDict.iterkeys() (通过keys迭代),myDict.itervalues() (通过values迭代),以及myDict.iteritems() (通过key/value对来迭代)


    文件


    文件对象生成的迭代器会自动调用readline()方法

    for eachLine in myFile.readlines(): 可以简化为 for eachLine in myFile:


    例:

    --------------------------------

    >>> myFile = open('test20.py')

    >>> for eachLine in myFile:

    ...     print eachLine,

    ...

    #!/usr/bin/env python

    while True:

       try:

           usr_input_1 = int(raw_input("please input the first word: ").strip())

           usr_input_2 = int(raw_input("please input the second word: ").strip())

           usr_input_3 = int(raw_input("please input the third word: ").strip())

           break

       except:

           print "please input the number!"

    list = [usr_input_1,usr_input_2,usr_input_3]

    average = sum(list)/len(list)

    print "The list is %s" %list

    print "The average of the list is %i" %average


    >>> myFile.close()

    --------------------------------------------------


    8.11.5 可变对象和迭代器

    循环列表的时候删除满足(或不满足)特定条件的项:

    for eachURL in allURLs:

       if not eachURL startswith('http://'):

    allURLs.remove(eachURL)


    在迭代字典key时,绝不能改变字典,否则不会继续执行下去:


    >>> myFile.close()

    >>> myDict = {'a':1,'b':2,'c':3,'d':4}

    >>> for eachKey in myDict:

    ...     print eachKey,myDict[eachKey]

    ...     del myDict[eachKey]

    ...

    a 1

    Traceback (most recent call last):

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

    RuntimeError: dictionary changed size during iteration


    8.11.6 如何创建迭代器


    iter(obj)检查传递的是不是序列,如果是,根据索引从0一直迭代到结束

    iter(fuc,sentinel)重复调用func,直到迭代器的下个值等于sentinel


    8.12 列表解析

    语法:

    [expr for iter_var in iterable]

    for循环迭代iterable对象的所有条目,前边的expr应用于序列的每个成员,最后的结果值是该表达式产生的列表


    例:

    计算序列成员的平方的lambda函数表达式

    >>> map(lambda x: x**2,range(6))

    [0, 1, 4, 9, 16, 25]

    列表解析方法:

    >>> [x ** 2 for x in range(6)]

    [0, 1, 4, 9, 16, 25]


    结合if语句,列表解析还提供一个扩展版本的语法:

    [expr for iter_var in iterable if cond_expr]



    使用filter()和lambda挑出序列的奇数:

    >>> seq = [11,10,9,9,10,10,9,8,23,9,7,18,12,11,12]

    >>> filter(lambda x: x % 2,seq)

    [11, 9, 9, 9, 23, 9, 7, 11]

    使用列表解析:

    >>> [x for x in seq if x % 2]

    [11, 9, 9, 9, 23, 9, 7, 11]


    矩阵样例:


    迭代一个有三行五列的矩阵


    >>> [(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('test20.py','r')

    >>> len([word for line in f for word in line.split()])

    57


    快速计算文件大小

    >>> import os

    >>> os.stat('test20.py').st_size

    497


    >>> f.seek(0)

    >>> sum([len(word) for line in f for word in line.split()])

    391


    8.13 生成器表达式


    列表解析:

    [expr for iter_var in iterable if cond_expr]


    生成器表达式:

    (expr for iter_var in iterable if cond_expr)


    >>> f = open('test20.py','r')                                  

    >>> sum(len(word) for line in f for word in line.split())      

    391


    交叉配对例子:

    >>> rows = [1, 2, 3, 17]                                  

    >>> def cols():

    ...    yield 56

    ...    yield 2

    ...    yield 1

    ...

    >>> x_product_pairs = ((i,j) for i in rows for j in cols())

    >>> for pair in x_product_pairs:

    ...   print pair          

    ...

    (1, 56)

    (1, 2)

    (1, 1)

    (2, 56)

    (2, 2)

    (2, 1)

    (3, 56)

    (3, 2)

    (3, 1)

    (17, 56)

    (17, 2)

    (17, 1)


    重构样例:


    我们通过一个寻找最长行的例子来看看如何改进代码


    例:

    ---------------------------

    #!/usr/bin/env python


    f = open('/etc/motd','r')

    longest = 0

    while True:

       linelen = len(f.readline().strip())

       if not linelen:

           break

       if linelen > longest:

           longest = linelen

    f.close()

    print longest

    -----------------------------


    版本1

    --------------------------------

    #!/usr/bin/env python

    f = open('/etc/motd','r')

    longest = 0

    allLines = f.readlines()

    f.close()

    for line in allLines:

      linelen = len(line.strip())

      if linelen > longest:

           longest = linelen

    print longest

    --------------------------------


    版本2

    --------------------------------

    #!/usr/bin/env python

    f = open('/etc/motd','r')

    longest = 0

    allLines = [x.strip() for x in f.readlines()]

    f.close()

    for line in allLines:

      linelen = len(line)

      if linelen > longest:

           longest = linelen

    print longest

    --------------------------------

    版本3

    ----------------------------------

    #!/usr/bin/env python


    f = open('/etc/motd', 'r')

    allLine = [x.strip() for x in f ]

    allLineList = []

    for Line in allLine:

       allLineList.append(len(Line))

    print max(allLineList)

    ----------------------------------

    版本4

    --------------------------------

    #!/usr/bin/env python


    f = open('/etc/motd', 'r')

    allLineLens = [len(x.strip()) for x in f ]

    print allLineLens

    f.close()

    print max(allLineLens)

    --------------------------------


    版本5

    ---------------------------------

    #!/usr/bin/env python

    f = open('/etc/motd','r')

    longest = max (len(x.strip()) for x in f)

    f.close()

    print longest

    ---------------------------------


    版本6 (最终版)

    ----------------------------------

    >>> print max(len(x.strip()) for x in open('/etc/motd','r'))      

    74

    -----------------------------------


    8.14 R相关模块


关键字