5.1 再谈 print 和 import
5.1.1 打印多个参数
print可用于打印多个表达式,条件是用逗号分隔它们。如果需要,可自定义分隔符。还可自定义结束字符串,以替换默认的换行符。
>>> print("I", "wish", "to", "register", "a", "complaint", sep="_") I_wish_to_register_a_complaint
print('Hello', end='~')
print('world!')
Hello~world!
5.1.2 导入时重命名
在语句末尾添加as子句并指定别名。
>>> import math as foobar
>>> foobar.sqrt(4)
2.0
5.2 赋值魔法
5.2.1 序列解包
可同时(并行)给多个变量赋值。
>>> x, y, z = 1, 2, 3
>>> print(x, y, z)
1 2 3
还可交换多个变量的值
>>> x,y,z = y,z,x
>>> x,y,z
(2, 3, 1)
这里执行的操作称为序列解包(或可迭代对象解包):将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中。解包的序列包含的元素个数必须与你在等号左边列出的目标个数相同,否则Python将引发异常。
可使用星号运算符(*)来收集多余的值,这样无需确保值和变量的个数相同。还可将带星号的变量放在其他位置。赋值语句的右边可以是任何类型的序列, 但带星号的变量最终包含的总是一个列表。 在变量和值的个数相同时亦如此。
>>> a, b, *rest = [1, 2, 3, 4]
>>> rest
[3, 4]
>>> a, *b, c = "abc"
>>> a, b, c
('a', ['b'], 'c')
5.2.2 链式赋值
多个变量关联同一个值:
x = y = somefunction()
5.2.3 增强赋值
增强赋值,适用于所有标准运算符,如+=、*=、/=、%=等,也可以用于其他数据类型。
>>> fnord = 'foo'
>>> fnord += 'bar'
>>> fnord *= 2
>>> fnord
'foobarfoobar'
5.3 代码块:缩进的乐趣
代码块是一组语句,是通过缩进代码(即在前面加空格)来创建的。在Python中,使用冒号:
指出接下来是一个代码块,并将该代码块中的每行代码都缩进相同的程度。
5.4 条件和条件语句
5.4.1 这正是布尔值的用武之地
下面的值都将被解释器视为假:False``None``0``""``()``[]``{}
其他值都为真。不需要显示转换。
5.4.2 有条件地执行和 if 语句
if语句,如果条件为真,就执行后续代码块;如果条件为假,就不执行。
name = input("What's your name")
if name.endswith('Gumby'):
print('Hello, Mr.Gumby')
5.4.3 else 子句
可使用else子句增加一种选择,
name = input("What's your name")
if name.endswith('Gumby'):
print('Hello, Mr.Gumby')
else:
print('Hello, stranger')
条件表达式(相当于三目运算符):
print('Hello, Mr.Gumby') if name.endswith('Gumby') else print('Hello, stranger')
5.4.4 elif 子句
elif是else if的缩写,由一个if子句和一个else子句组合而成,也就是包含条件的else子句。
num = int(input('Enter a number: '))
if num > 0:
print('The number is positive')
elif num < 0:
print('The number is negative')
else:
print('The number is zero')
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的成员 |
Python也支持链式比较:可同时使用多个比较运算符,如0 < age < 100。
相等运算符
:确定两个对象是否相等,可使用比较运算符,用两个等号(==)表示
is
:相同运算符:is检查两个对象是否相同,是否是同一个对象。不要将is用于数和字符串等不可变的基本值。鉴于Python在内部处理这些对象的方式,这样做的结果是不可预测的。
in
:成员资格运算符
字符串和序列的比较
:字符串是根据字符的字母排列顺序进行比较的。
>>> "alpha" < "beta"
True
>>> [1, 2] < [2, 1]
True
>>> [2, [1, 4]] < [2, [1, 5]]
True
2. 布尔运算符
布尔运算符包括and,or和not。通过使用这三个运算符,能以任何方式组合真值。布尔运算符是短路逻辑。
表达式x and y,如果x为假,这个表达式将返回x,否则返回y。
表达式x or y中,如果x为真,就返回x,否则返回y。
5.4.7 断言
关键字assert可要求某些条件得到满足(如核实函数参数满足要求或为初始测试和调试提供帮助),还可在条件后面添加一个字符串,对断言做出说明。
>>> age = 10
>>> assert 0 < a < 100
>>> age = -1
>>> assert 0 < age < 100, 'The age must be realistic'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: The age must be realistic
5.5 循环
5.5.1 while 循环
while语句用于循环
name = ''
while not name:
name = input('Please enter your name: ')
print('Hello, {}!'.format(name))
5.5.2 for 循环
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in numbers:
print(number)
Python提供了一个创建范围的内置函数。
>>> range(0, 10)
range(0, 10)
>>> list(range(0, 10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in range(1,101):
print(number)
5.5.3 迭代字典
要遍历字典的所有关键字,可像遍历序列那样使用普通的for语句。
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print(key, 'corresponds to', d[key])
for key, value in d.items():
print(key, 'corresponds to', value)
5.5.4 一些迭代工具
1. 并行迭代
并行迭代工具是内置函数zip,它将两个序列“缝合”起来,并返回一个由元组组成的序列。返回值是一个适合迭代的对象,要查看其内容,可使用list将其转换为列表。当序列的长度不同时,函数zip将在最短的序列用完后停止。
names = ['anne', 'beth', 'george', 'damon']
ages = [12, 45, 32, 102]
print(list(zip(names, ages)))
for name, age in zip(names, ages):
print(name, 'is', age, 'years old')
print(list(zip(range(10), range(4), range(100))))
[('anne', 12), ('beth', 45), ('george', 32), ('damon', 102)]
anne is 12 years old
beth is 45 years old
george is 32 years old
damon is 102 years old
[(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3)]
2. 迭代时获取索引
一种方法是加入一个index变量,类似于原来的:for(i = 0;i < str.length(); i++)。
index = 0
for string in strings:
if 'xxx' in string:
strings[index] = '[censored]'
index += 1
另一种方案是采用内置函数enumrate
。这个函数让你能够迭代索引-值对,其中的索引是自动提供的。
for index, string in enumerate(strings):
if 'xxx' in string:
strings[index] = '[censored]'
3. 反向迭代和排序后再迭代
函数reverse和sorted可用于任何序列或可迭代的对象,且不就地修改对象,而是返回反转和排序后的版本。
>>> sorted('Hello, world!')
[' ', '!', ',', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(reversed('Hello, world!'))
['!', 'd', 'l', 'r', 'o', 'w', ' ', ',', 'o', 'l', 'l', 'e', 'H']
sorted返回一个列表,reversed返回一个可迭代对象。要按字母表排序,可先转换为小写。为此,可将sort或sorted的key参数设置为str.lower。例如,sorted("aBc", key=str.lower)返回['a', 'B', 'c']。
5.5.5 跳出循环
- break 要跳出循环,可使用break。
- continue 它结束当前迭代,并跳到下一次迭代开头。
5.5.6 循环中的 else 子句
如何判断循环是提前结束还是正常结束的,之前可在循环开始前定义一个布尔变量并将其设置为False,再在跳出循环时将其设置为True。python中更简单的办法是在循环中添加一条else子句,它仅在没有调用break时才执行。无论是在for循环还是while循环中,都可使用continue、break和else子句。
from math import sqrt
for n in range(99, 81, -1):
root = sqrt(n)
if root == int(root):
print(n)
break
else:
print("Didn't find it!")
5.6 简单推导
列表推导是一种从其他列表创建列表的方式, 类似于数学中的集合推导。
>>> [x * x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10) if x % 3 == 0]
[0, 9, 36, 81]
>>> [(x, y) for x in range(3) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)
使用圆括号代替方括号并不能实现元组推导,而是将创建生成器,然而,可使用花括号来执行字典推导。
squares = {i:"{} squared is {}".format(i, i**2) for i in range(10)}
print(squares[8])
8 squared is 64
5.7 三人行
5.7.1 什么都不做
pass语句可以作为占位符。
5.7.2 使用 del 删除
del语句删除对象名称
5.7.3 使用 exec 和 eval 执行字符串及计算其结果
函数exec将字符串作为代码执行。
str = 'print("Hello world")'
exec(str)
Hello world
在大多数情况下,还应向它提供一个字典以充当命名空间,防止代码污染命名空间。可向exec提供两个命名空间:一个全局的和一个局部的。提供的全局命名空间必须是字典,而提供的局部命名空间可以是任何映射。这一点也适用于eval。
x = 10
expr = """
z = 30
sum = x + y + z
print(sum)
"""
def func():
y = 20
exec(expr)
exec(expr,{'x': 1, 'y': 2, 'z': 3})
exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
func()
60
33
34
eval是一个类似于exec的内置函数。exec执行一系列Python语句,而eval计算用字符串表示的Python表达式的值,并返回结果
- eval()函数只能计算单个表达式的值,而exec()函数可以动态运行代码段。
- eval()函数可以有返回值,而exec()函数返回值永远为None。
网友评论