yzqzs 发表于 2018-8-8 09:24:15

[PYTHON] 核心编程笔记之八-Python条件和循环

  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 or )
  >>> 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
  ...
  Liu Cathy
  Liu Terry
  Liu Joe
  Liu heather
  Liu Lucy
  >>> len(nameList)
  5
  >>> range(len(nameList))
  
  使用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)
  
  只给定两个参数,省略step,step就使用默认1
  >>> range(3,7)
  
  例:
  >>> 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)
  
  >>> 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
  ...
  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 =
  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
  ...   del myDict
  ...
  a 1
  Traceback (most recent call last):
  File "<stdin>", line 1, in <module>

  RuntimeError: dictionary changed>  8.11.6 如何创建迭代器
  iter(obj)检查传递的是不是序列,如果是,根据索引从0一直迭代到结束
  iter(fuc,sentinel)重复调用func,直到迭代器的下个值等于sentinel
  8.12 列表解析
  语法:
  
  for循环迭代iterable对象的所有条目,前边的expr应用于序列的每个成员,最后的结果值是该表达式产生的列表
  例:
  计算序列成员的平方的lambda函数表达式
  >>> map(lambda x: x**2,range(6))
  
  列表解析方法:
  >>>
  
  结合if语句,列表解析还提供一个扩展版本的语法:
  
  使用filter()和lambda挑出序列的奇数:
  >>> seq =
  >>> filter(lambda x: x % 2,seq)
  
  使用列表解析:
  >>>
  
  矩阵样例:
  迭代一个有三行五列的矩阵
  >>> [(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()
  57
  快速计算文件大小
  >>> import os
  >>> os.stat('test20.py').st_size
  497
  >>> f.seek(0)
  >>> sum()
  391
  8.13 生成器表达式
  列表解析:
  
  生成器表达式:
  (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 =
  >>> 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 =
  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 =
  allLineList = []
  for Line in allLine:
  allLineList.append(len(Line))
  print max(allLineList)
  ----------------------------------
  版本4
  --------------------------------
  #!/usr/bin/env python
  f = open('/etc/motd', 'r')
  allLineLens =
  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相关模块
页: [1]
查看完整版本: [PYTHON] 核心编程笔记之八-Python条件和循环