Python学习笔记【五】——《python基础教程》:: 条件、循环和其他语句

时间:2021-08-28 18:40:49

第5章 条件、循环和其他语句

5.1. print和import的更多信息

5.1.1. 使用逗号输出

  1. print打印多个表达式时,用逗号将他们隔开。结果中各个表达式中会自动添加空格。

    >>> print 'hello','world,','holly'
    hello world, holly
  2. 若希望print结果中某个表达式后添加”,”,需要print语句中该表达式和”,”之间添加连接符”+”

    >>> print 'hello','world'+',','holly'
    hello world, holly
  3. print语句最后添加”,”,那么下一行的print语句打印内容会连接在当前行打印内容之后。


    #test.py

    print 'hello',
    print 'world'

    #./test.py

    hello world

5.1.2. 把某件事作为另一件事导入

#为模块提供别名
>>> import math as foobar
>>> foobar.sqrt(4)
2.0
#为函数提供别名
>>> from math import sqrt as foobar
>>> foobar(4)
2.0

可用于解决不同模块中函数重名问题

from module1 import open as open1
from module2 import open as open2

5.2. 赋值魔法

5.2.1. 序列解包

序列解包(sequence unpacking)/可选代解包:将多个值的序列解开,然后放到变量的序列中。下述代码可以形象描述这一功能:

>>> value = 1, 2, 3
>>> value
(1, 2, 3)
>>> x, y, z = value
>>> x, y, z
(1, 2, 3)
#上述赋值操作可以用序列解包实现
>>> x, y, z = 1, 2, 3
>>> x, y, z
(1, 2, 3)

★解包列中,元素数量必须和放在赋值符号=左边的变量数量完全一致

5.2.2. 链式赋值

链式赋值(chained assignment):将同一个值赋给多个变量。

>>> x = y = [1, 2]
>>> x, y
([1, 2], [1, 2])

5.2.3. 增量赋值

增量赋值(augmented assignment):+= *= /= %=

5.3. 语句块:缩排的乐趣

  1. 定义:条件为真(条件语句)时执行或执行多次(循环语句)的一组语句。
  2. 创建:代码前放置空格缩进语句可创建语句块。块中的每行都应该缩进同样的量。
  3. 语句块开始标志”:”

5.3.1. 这就是布尔变量的作用

  1. 标准布尔值:True 和 False
  2. Python解释器会将以下表达式解释为False:False None 0 “” () [] {}
    其他表达式解释为True。
    ★区分原则类似于“有些东西”和“没有东西”
  3. bool()函数可以将表达式转换为布尔变量

    >>> bool("ddd")
    True
    >>> bool("")
    False
    >>> bool(0)
    False
    >>> bool(3)
    True

    ★所有值都可用作布尔值,Python会自动对其进行转换,无需用户显示转换
    ★尽管很多值都可以被看作False,但是他们本身并不相等,即bool([])==bool(“”),但是[]!=”“

5.4.2.~5.4.4. 条件执行和if语句/else子句/elif子句

类似C语言,代码如下

#if/elif/else下一行为新的语句块,因此在if/elif/else条件判断结束后添加":"作为心语句块的开始标志。
#if/elif/else下一行的新语句块缩进表示新的语句块
num = input("Enter a number: ")
if num > 0:
print 'positive.'
elif num < 0:
print 'negative.'
else:
print 'zero'

5.4.5. 嵌套代码块

类似C语言,代码如下

name = raw_input("What's your name? ")
if name.endswith('holly'):
if name.startswith('Mr.'):
print 'hello, Mr. holly'
elif name.startswith('Mrs.'):
print 'hello, Mrs. holly'
else:
print 'hello, holly'
else:
print 'hello, stranger.'

5.4.6. 更复杂的条件

1. 比较运算符

  • 比较运算符
表达式 描述
x == y x等于y
x < y x小于y
x > y x大于y
x >= y x大于等于y
x <= y x小于等于y
x != y x不等于y
x is y x和y是同一个对象
x is not y x和y是不同对象
x in y x是y容器的成员
x not in y x不是y容器的成员

★只有相同或近似类型(整型和浮点型)的对象时,比较才有意义。
★反之,不同类型(例如整型和字符串)进行比较,在程序执行的时候得到的结果不确定。在Python3.0之后不兼容类型对象比较已取消。
2. Python中比较运算可以连接,例如:1 < age < 100。

2. 相等运算符

“==”:两个对象是否相等

3. is:同一性运算

is:两个变量是否等同(同一个对象)
下面例子对”==”和is进行比较。

>>> x=1, 2, 3
>>> y=1, 2, 3
>>> z=x
>>> x, y, z
((1, 2, 3), (1, 2, 3), (1, 2, 3))
#x == y 为 True 表示 x 与 y 的值相同
>>> x==y
True
#x is y 为 False 表示 x 与 y 不是同一个对象
>>> x is y
False
#x is z 为 True 表示 x 与 z 是同一个对象
>>> x == z
True
#使用 id() 可见,x 与 z 为同一个对象
>>> id(x), id(y), id(z)
(140333714168160, 140333714168000, 140333714168160)

4. in:成员资格运算符:参见2.2.5

5. 字符串和序列比较

  1. 字符串按字母顺序排列进行比较,直到遇到第一个不相同的字符。

    >>> 'addd'<'bccc'
    True
  2. 比较序列与字符串类似

    >>> [2, [2, 3]]<[1, [2, 3]]
    False

6. 布尔运算符

  1. 布尔运算符:and, or, not
  2. 布尔运算符特性:短路逻辑(short-circuit logic)或惰性求值(lazy evaluation)。关于运算符的上述特性有以下说明,其实与C语言相同。
运算符 短路逻辑、惰性求值说明
x and y 若x为False,立刻返回False;若x为True,返回y的值
x or y 若x为True,立刻返回True;若x为False,返回y的值

该特性避免了无用代码的执行,例如:

>>> name = raw_input("What's your name? ") or 'unknown'
What's your name?
>>> name
'unknown'

5.4.7. 断言

assert:要求某些条件必须为真,否则程序崩溃。

>>> age = 0
>>> assert 1 < age
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError

5.5. 循环

5.5.1. while循环

格式如下:

while condition:
program block

例如:

>>> n = 1
>>> while n <= 10:
... print n
... n += 1
...
1
2
3
4
5
6
7
8
9
10

5.5.2. for循环

  1. 常用于条件为迭代某个序列的情况。
  2. 格式:

    for variable in sequence:
    program block

    例如:

    >>> for number in [1,2,3,]:
    ... print number
    ...
    1
    2
    3
  3. Python内建的范围函数range(),可用于产生序列

    >>> range(1, 10)
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> range(10)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    ★另一内建范围函数xrange(),接口与range()类似,但是一次只创建一个数。当迭代序列规模大时高效。Python3.0之后,range被换成xrange风格的函数。

5.5.3. 循环遍历字典

d={'x':1,'y':2,'z':3}
>>> for a in d:
... print a, d[a]
...
y 2
x 1
z 3

★字典元素的顺序没有定义。因此遍历字典时,能保证键-值都被处理,但是处理顺序不确定。

5.5.4. 一些迭代工具

1. 并行迭代

使用zip函数将两个序列”压缩”为一个元组的列表,然后再循环中解包元组。

>>> names = ['aaa', 'bbb', 'ccc']
>>> ages = [12, 23, 34]
#使用zip函数压缩两个序列
>>> zip(names, ages)
[('aaa', 12), ('bbb', 23), ('ccc', 34)]
#再循环中解包zip函数压缩的序列
>>> for name, age in zip(names, ages):
... print name, 'is', age, 'years old'
...
aaa is 12 years old
bbb is 23 years old
ccc is 34 years old

zip函数可以作用于任意多的序列。zip函数“压缩”不等长序列时,在最短的序列“用完”时停止。

#由于names和ages只有3个元素,adds有4个元素,zip只打包3个元组
>>> names = ['aaa', 'bbb', 'ccc']
>>> ages = [12, 23, 34]
>>> adds = ['yantai', 'shanghai', 'qingdao', 'beijing']
>>> zip(names, ages, adds)
[('aaa', 12, 'yantai'), ('bbb', 23, 'shanghai'), ('ccc', 34, 'qingdao')]

2. 编号迭代

使用enumerate函数可以再提供索引的地方迭代索引-值对。

>>> adds = ['yantai', 'shanghai', 'qingdao', 'beijing']
>>> for index, add in enumerate(adds):
... print index, add
...
0 yantai
1 shanghai
2 qingdao
3 beijing

3. 反转和排序迭代

  1. reversed和sorted:作用与任何序列和可迭代对象,返回处理后的版本,不是原地修改。
函数 说明
reversed 返回翻转后的可迭代的对象
sorted 返回排序后的列表

2. 使用示例如下

#sorted
>>> sorted([3,5,1,3,9])
[1, 3, 3, 5, 9]
#reversed
>>> reversed('hello, world!')
<reversed object at 0x7faea7e3e290>
>>> list(reversed('hello, world!'))
['!', 'd', 'l', 'r', 'o', 'w', ' ', ',', 'o', 'l', 'l', 'e', 'h']

5.5.5. 跳出循环

1. break:结束(跳出)循环

>>> for i in range(10):
... print i
... if i == 3:
... break
...
0
1
2
3

2. continue:结束当前迭代,跳到下一轮循环的开始。

>>> for i in range(10):
... if i % 2 == 0:
... continue
... print i
...
1
3
5
7
9

★continue语句可以被其他语句代替,并不是最本质的。应习惯使用break,因为在while True语句中经常用到他。

3. while True/break习语

while True:
initilization
if condition: break
dosomething
  1. while True实现永远不会自己停止的循环。
  2. if/break将循环分为两部分:第1部分负责初始化,第2部分在循环条件为真的情况下使用第1部分内初始化好的数据。

5.5.6. 循环中的else子句

在循环内使用break跳出前,可以执行一些操作;若希望在其他情况下跳出时执行某些操作,可使用循环中的else子句。

>>> for i in [1,2,3,4,5]:
... max = input("Please input number: ")
... if i < max:
... break
... else:
... print 'No valid max.'
...
Please input number: 1
Please input number: 1
Please input number: 1
Please input number: 1
Please input number: 1
No valid max.

5.6. 列表推导式——轻量级循环

列表推导式(list comprehension)是利用其他列表创建新列表。

>>> [x*x for x in range(5)]
[0, 1, 4, 9, 16]
>>>
>>> [(x, y) for x in range(5) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2)]
>>>
>>> [(x, y) for x in range(5) for y in range(3) if x == y]
[(0, 0), (1, 1), (2, 2)]

通过上述例子可见,列表推导式与其他语句之间可相互转换
列表推导式格式为:

[programblock if condition1 for condition2 ... for conditionM if conditionN]

相当于以下语句块

if condition1:
for condition2:
...
for conditionM:
if conditionN:
programblock

其中if和for没有前后和数量要求,可以*组合。

5.7. 三人行

5.7.1. 什么都没发生

pass语句可做占位符使用

>>> pass
>>>

5.7.2. 使用del删除

使用del可以删除一个对象的引用和应用的名字,但是不会删除引用的名字。当没有引用名字绑定到某个对象上时,对象无法获取和使用,但是该对象依然占用内存,此时Python解释器会删除该对象,释放空间(垃圾收集)。

>>> x = [1,2,3]
>>> y = x
>>> x
[1, 2, 3]
>>> y
[1, 2, 3]
#删除x后,x名字被删除但是它绑定的列表并没有删除,因此y依然可用
>>> del x
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> y
[1, 2, 3]

5.7.3. 使用exec和eval执行和求值字符串

1. exec:执行一个字符串的语句

>>> exec 'print "hello, world"'
hello, world

exec可以动态创建代码字符串。但是,字符串中包含的代码内容无法获得,安全起见,可以在执行exec时通过增加 in scope,将字符串代码放到名为scope的命名空间中。

#sqrt被定义为一个整型变量,占用了Python内建函数的名称,导致函数执行错误
>>> from math import sqrt
>>> exec "sqrt=1"
>>> sqrt(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
#上述问题可以通过添加命名空间字典来解决
>>> from math import sqrt
>>> scope={}
>>> exec "sqrt=1" in scope
>>> sqrt(4)
2.0
#查看字典scope,其中除了定义的sqrt键-值对,还包括内建的__builtins__字典,自动包括所有内建函数和值
>>> scope
{'__builtins__': {'bytearray': <type 'bytearray'>, 'IndexError': <type 'exceptions.IndexError'>, 'all': <built-in function all>, 'help': Type help() for interactive help, or help(object) for help about object., 'vars': <built-in function vars>, 'SyntaxError': <type 'exceptions.SyntaxError'>, 'unicode': <type 'unicode'>, 'UnicodeDecodeError': <type 'exceptions.UnicodeDecodeError'>, 'memoryview': <type 'memoryview'>, 'isinstance': <built-in function isinstance>, 'copyright': Copyright (c) 2001-2016 Python Software Foundation.
All Rights Reserved.

Copyright (c) 2000 BeOpen.com.
All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved., 'NameError': <type 'exceptions.NameError'>, 'BytesWarning': <type 'exceptions.BytesWarning'>, 'dict': <type 'dict'>, 'input': <built-in function input>, 'oct': <built-in function oct>, 'bin': <built-in function bin>, 'SystemExit': <type 'exceptions.SystemExit'>, 'StandardError': <type 'exceptions.StandardError'>, 'format': <built-in function format>, 'repr': <built-in function repr>, 'sorted': <built-in function sorted>, 'False': False, 'RuntimeWarning': <type 'exceptions.RuntimeWarning'>, 'list': <type 'list'>, 'iter': <built-in function iter>, 'reload': <built-in function reload>, 'Warning': <type 'exceptions.Warning'>, '__package__': None, 'round': <built-in function round>, 'dir': <built-in function dir>, 'cmp': <built-in function cmp>, 'set': <type 'set'>, 'bytes': <type 'str'>, 'reduce': <built-in function reduce>, 'intern': <built-in function intern>, 'issubclass': <built-in function issubclass>, 'Ellipsis': Ellipsis, 'EOFError': <type 'exceptions.EOFError'>, 'locals': <built-in function locals>, 'BufferError': <type 'exceptions.BufferError'>, 'slice': <type 'slice'>, 'FloatingPointError': <type 'exceptions.FloatingPointError'>, 'sum': <built-in function sum>, 'getattr': <built-in function getattr>, 'abs': <built-in function abs>, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'print': <built-in function print>, 'True': True, 'FutureWarning': <type 'exceptions.FutureWarning'>, 'ImportWarning': <type 'exceptions.ImportWarning'>, 'None': None, 'hash': <built-in function hash>, 'ReferenceError': <type 'exceptions.ReferenceError'>, 'len': <built-in function len>, 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
for supporting Python development. See www.python.org for more information., 'frozenset': <type 'frozenset'>, '__name__': '__builtin__', 'ord': <built-in function ord>, 'super': <type 'super'>, '_': None, 'TypeError': <type 'exceptions.TypeError'>, 'license': Type license() to see the full license text, 'KeyboardInterrupt': <type 'exceptions.KeyboardInterrupt'>, 'UserWarning': <type 'exceptions.UserWarning'>, 'filter': <built-in function filter>, 'range': <built-in function range>, 'staticmethod': <type 'staticmethod'>, 'SystemError': <type 'exceptions.SystemError'>, 'BaseException': <type 'exceptions.BaseException'>, 'pow': <built-in function pow>, 'RuntimeError': <type 'exceptions.RuntimeError'>, 'float': <type 'float'>, 'MemoryError': <type 'exceptions.MemoryError'>, 'StopIteration': <type 'exceptions.StopIteration'>, 'globals': <built-in function globals>, 'divmod': <built-in function divmod>, 'enumerate': <type 'enumerate'>, 'apply': <built-in function apply>, 'LookupError': <type 'exceptions.LookupError'>, 'open': <built-in function open>, 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'basestring': <type 'basestring'>, 'UnicodeError': <type 'exceptions.UnicodeError'>, 'zip': <built-in function zip>, 'hex': <built-in function hex>, 'long': <type 'long'>, 'next': <built-in function next>, 'ImportError': <type 'exceptions.ImportError'>, 'chr': <built-in function chr>, 'xrange': <type 'xrange'>, 'type': <type 'type'>, '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", 'Exception': <type 'exceptions.Exception'>, 'tuple': <type 'tuple'>, 'UnicodeTranslateError': <type 'exceptions.UnicodeTranslateError'>, 'reversed': <type 'reversed'>, 'UnicodeEncodeError': <type 'exceptions.UnicodeEncodeError'>, 'IOError': <type 'exceptions.IOError'>, 'hasattr': <built-in function hasattr>, 'delattr': <built-in function delattr>, 'setattr': <built-in function setattr>, 'raw_input': <built-in function raw_input>, 'SyntaxWarning': <type 'exceptions.SyntaxWarning'>, 'compile': <built-in function compile>, 'ArithmeticError': <type 'exceptions.ArithmeticError'>, 'str': <type 'str'>, 'property': <type 'property'>, 'GeneratorExit': <type 'exceptions.GeneratorExit'>, 'int': <type 'int'>, '__import__': <built-in function __import__>, 'KeyError': <type 'exceptions.KeyError'>, 'coerce': <built-in function coerce>, 'PendingDeprecationWarning': <type 'exceptions.PendingDeprecationWarning'>, 'file': <type 'file'>, 'EnvironmentError': <type 'exceptions.EnvironmentError'>, 'unichr': <built-in function unichr>, 'id': <built-in function id>, 'OSError': <type 'exceptions.OSError'>, 'DeprecationWarning': <type 'exceptions.DeprecationWarning'>, 'min': <built-in function min>, 'UnicodeWarning': <type 'exceptions.UnicodeWarning'>, 'execfile': <built-in function execfile>, 'any': <built-in function any>, 'complex': <type 'complex'>, 'bool': <type 'bool'>, 'ValueError': <type 'exceptions.ValueError'>, 'NotImplemented': NotImplemented, 'map': <built-in function map>, 'buffer': <type 'buffer'>, 'max': <built-in function max>, 'object': <type 'object'>, 'TabError': <type 'exceptions.TabError'>, 'callable': <built-in function callable>, 'ZeroDivisionError': <type 'exceptions.ZeroDivisionError'>, 'eval': <built-in function eval>, '__debug__': True, 'IndentationError': <type 'exceptions.IndentationError'>, 'AssertionError': <type 'exceptions.AssertionError'>, 'classmethod': <type 'classmethod'>, 'UnboundLocalError': <type 'exceptions.UnboundLocalError'>, 'NotImplementedError': <type 'exceptions.NotImplementedError'>, 'AttributeError': <type 'exceptions.AttributeError'>, 'OverflowError': <type 'exceptions.OverflowError'>}, 'sqrt': 1}

2. eval:计算字符串形式的Python表达式,并返回结果。

>>> eval(raw_input("Please input an arithmetic expression: "))
Please input an arithmetic expression: 1+4*5
21

eval也像exec一样,有命名空间的问题。