5.1 再谈import和print

5.1.1 打印多个参数

可同时打印多个表达式,条件是用逗号分隔它们:在参数之间插入了一个空格字符

print('Age:', 42)
# Age: 42
name = 'Gumby'
salutation = 'Mr.'
greeting = 'Hello,'
print(greeting, salutation, name)
# Hello, Mr. Gumby

5.1.2 导入时重命名

从模块导入时,通常使用import somemodule或者使用from somemodule import somefunction。还有一种办法:在语句末尾添加as子句并指定别名。

import math as foobar
foobar.sqrt(4)

5.2 赋值魔法

5.2.1 序列解包

可同时(并行)给多个变量赋值,使用这种方式还可交换多个变量的值。

x,y,z = 1,2,3
print(x,y,z)
# 1,2,3
x,y = y,x
print(x, y, z)
# 2,1,3

实际上,这里执行的操作称为序列解包(或可迭代对象解包):将一个序列(或任何可迭代 对象)解包,并将得到的值存储到一系列变量中。

values = 1, 2, 3
# values (1,2,3)
x, y, z = values
# x = 1
scoundrel = {'name': 'Robin', 'girlfriend': 'Marion'}
key, value = scoundrel.popitem()
# key = 'girlfriend'

这在使用返回元组(或其他序列或可迭代对象)的函数或方法时很有用。这让函数能够返回被打包成元组的多个值,然后通过一条赋值语句轻松地访问这些值。

5.2.2 链式赋值

链式赋值是一种快捷方式,用于将多个变量关联到同一个值。
x = y = somefunction()

5.2.3 增强赋值

从而写成x += 1。这称为增强赋值,适用于所有标准运算符,如*、/、%等。

5.3 代码块:缩进的乐趣

代码块是一组语句,可在满足条件时执行(if语句),可执行多次(循环),等等。代码块是 通过缩进代码(即在前面加空格)来创建的。
在Python中,使用冒号(:)指出 接下来是一个代码块,并将该代码块中的每行代码都缩进相同的程度。发现缩进量与之前相同时, 你就知道当前代码块到此结束了。

5.4 条件和条件语句

if语句,让你能够有条件地执行代码。这意味着如果条件(if和冒号之间的表达式) 为前面定义的真,就执行后续代码块(这里是一条print语句);如果条件为假,就不执行(你应 该猜到了)。可使用else子句增加一种选择。
还有一个与if语句很像的“亲戚”,它就是条件表达式——C语言中三目运算符的Python版本。

status = "friend" if name.endswith("Gumby") else "stranger"

要检查多个条件,可使用elif。你可将if语句放在其他if语句块中。

5.4.1 条件

is:相同运算符

is检查两个对象是否相同(而不是相等)。变量x和y指向同 一个列表,而z指向另一个列表(其中包含的值以及这些值的排列顺序都与前一个列表相同)。这 两个列表虽然相等,但并非同一个对象。

x = y = [1, 2, 3] 
z = [1, 2, 3]
x == y
# True
x == z
# True
x is y
# True
x is z
# False

总之,==用来检查两个对象是否相等,而is用来检查两个对象是否相同(是同一个对象)。

布尔运算符

运算符and是一个布尔运算符。它接受两个真值,并在这两个值都为真时返回真,否则返回 假。还有另外两个布尔运算符:or和not。通过使用这三个运算符,能以任何方式组合真值。
短路逻辑(或者延迟求值)

5.4.7 断言

让程序在错误条件出现时立即崩溃胜过以后再崩溃,可在语句中使用关键字assert。还可在条件后面添加一个字符串,对断言做出说明。

age = -1
assert 0 < age < 100, 'The age must be realistic'

5.5 循环

5.5.1 while循环

x=1
while x <= 100:
	print(x) 
	x += 1

5.5.2 for循环

为序列(或其他可迭代对象)中每个元素执行 代码块。

words = ['this', 'is', 'an', 'ex', 'parrot'] 
for word in words:
	print(word)
list(range(0, 10))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

创建范围的内置函数range。范围类似于切片。它们包含起始位置(这里为0),但不包含结束位置(这里为10)。

5.5.3 迭代字典

可像遍历序列那样使用普通的for语句。d.items以元组的方式返回键值对

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. 并行迭代

有时候,你可能想同时迭代两个序列。假设有下面两个列表:如果要打印名字和对应的年龄,可以像下面这样做:

names = ['anne', 'beth', 'george', 'damon'] 
ages = [12, 45, 32, 102]
for i in range(len(names)):
	print(names[i], 'is', ages[i], 'years old')

一个很有用的并行迭代工具是内置函数zip,它将两个 序列“缝合”起来,并返回一个由元组组成的序列。“缝合”后,可在循环中将元组解包。

for name, age in zip(names, ages): 
	print(name, 'is', age, 'years old')

2. 迭代时获取索引

在有些情况下,你需要在迭代对象序列的同时获取当前对象的索引。使用内置函数 enumerate。

for index, string in enumerate(strings): 
	if 'xxx' in string:
    	strings[index] = '[censored]'

5.5.5 跳出循环

要结束(跳出)循环,可使用break。语句continue没有break用得多。它结束当前迭代,并跳到下一次迭代开头。这基本上意味 着跳过循环体中余下的语句,但不结束循环。

from math import sqrt
for n in range(99, 0, -1):
	root = sqrt(n)
	if root == int(root):
    	print(n)
        break

5.6 简单推导

列表推导是一种从其他列表创建列表的方式。列表推导的工作原 理非常简单,有点类似于for循环。

[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)]
#

5.7 三人行

5.7.1 什么都不做

有时候什么都不用做。在你编写代码时,可将其用作占位符。

if name == 'Ralph Auldus Melish': 
	print('Welcome!')
elif name == 'Enid': 
# 还未完成......
	pass
elif name == 'Bill Gates':
	print('Access Denied')

5.7.2 使用del删除

另一种办法是使用del语句。这不仅会删除到对象的引用,还会删除名称本身。对于你不再使用的值,Python解释器会立即将其删除,这称为垃圾回收。del删除的是名称,而不是值。

x = 1
del x

5.7.3 使用exec和eval执行字符串及计算其结果

1. exec

函数exec将字符串作为代码执行。

exec("print('Hello, world!')") 
# Hello, world!

函数exec主要用于动态地创建代码字符串。在大多数情况下,还应向它传递一个 命名空间——用于放置变量的地方;

2. eval

eval是一个类似于exec的内置函数。exec执行一系列Python语句,而eval计算用字符串表示 的Python表达式的值,并返回结果(exec什么都不返回,因为它本身是条语句)。