python基础——5章 条件、循环、序列解包、列表推导、迭代工具

赋值魔法

5.2.1 序列解包
>>> x, y, z = 1, 2, 3
>>> x, y, z = z, x, y
# 交换多个变量的值, 称为序列解包:将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中
>>> 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' 
>>> value 
'Marion' 
# 可使用星号运算符(*)来收集多余的值,这样无需确保值和变量的个数相同
>>> a, b, *rest = [1, 2, 3, 4] 
>>> rest 
[3, 4] 
# 还可将带星号的变量放在其他位置。 
>>> name = "Albus Percival Wulfric Brian Dumbledore" 
>>> first, *middle, last = name.split() 
>>> middle 
['Percival', 'Wulfric', 'Brian'] 
# 赋值语句的右边可以是任何类型的序列,但带星号的变量最终包含的总是一个列表。在变量和值的个数相同时亦如此。 
>>> a, *b, c = "abc" 
>>> a, b, c 
('a', ['b'], 'c') 
# 这种收集方式也可用于函数参数列表中(参见第6章)。 
5.2.2 链式赋值
x = y = somefunction()
5.2.3 增强赋值

*= += 等,增强赋值也可用于其他数据类型

5.3 代码块:缩进

缩进的标准做法是只使用空格,且每级缩进4个空格
在很多语言中,都使用一个特殊的单词或字符(如begin或{)来标识代码块的起始位置,并使用另一个特殊的单词或字符(如end或})来标识结束位置。在Python中,使用冒号(:)指出接下来是一个代码块,并将该代码块中的每行代码都缩进相同的程度。发现缩进量与之前相同时,你就知道当前代码块到此结束了。

5.4 条件和条件语句

5.4.1 条件
  • 下面的值都将被解释器视为假:
    False None 0 “” () [] {}
    换而言之,标准值False和None、各种类型(包括浮点数、复数等)的数值0、空序列(如空字符串、空元组和空列表)以及空映射(如空字典)都被视为假,而其他各种值都被视为真 ① ,包括特殊值True ② 。
    ① 至少对内置类型值来说如此。你在第9章将看到,对于自己创建的对象,解释为真还是假由你决定。
    ② 正如Python老手Laura Creighton指出的,这种差别类似于“有些东西”和“没有东西”的差别,而不是真和假的差别。
  • 布尔值True和False属于类型bool,而bool与list、str和tuple一样,可用来转换其他的值。

注意 虽然[]和"“都为假(即bool([]) == bool(”") == False),但它们并不相等(即[] != “”)。对其他各种为假的对象来说,情况亦如此(一个更显而易见的例子是() != False)。

5.4.2 语句

str.endswith()

name = input('What is your name?') 
if name.endswith('Gumby'):  
   print('Hello, Mr. Gumby') 
else: 
   print('Hello, stranger') 

条件表达式——C语言中三目运算符的Python版本。
下面的表达式使用if和else确定其值:

status = "friend" if name.endswith("Gumby") else "stranger"
5.4.6 更复杂的条件

表5-1 Python比较运算符

表 达 式描 述
x == yx 等于y
x < yx小于y
x > yx大于y
x >= yx大于或等于y
x <= yx小于或等于y
x != yx不等于y
x is yx和y是同一个对象
x is not yx和y是不同的对象
x in yx是容器(如序列)y的成员
x not in yx不是容器(如序列)y的成员

与赋值一样,Python也支持链式比较:可同时使用多个比较运算符,如0 < age < 100。

  • 相等(==)而不是(=)
  • 相同运算符:is
  • in:成员资格运算符
  • 字符串和序列的比较

字符串是依据字符的字母排列顺序进行比较的,字母都是Unicode字符,是按码点排列的,要获悉字母的顺序值,可以使用函数ord()。这个函数的作用与函数chr()相反。

>>> ord("★") 
9733
>>> chr(9733) 
'★' 

短路逻辑和条件表达式

布尔运算符有个有趣的特征:只做必要的计算。例如,仅当x和y都为真时,表达式x and y才为真。因此如果x为假,这个表达式将立即返回假,而不关心y。实际上,如果x为假,这个表达式将返回x,否则返回y。(这将提供预期的结果,你明白了其中的原理吗?)这种行为称为短路逻辑(或者延迟求值):布尔运算符常被称为逻辑运算符,如你所见,在有些情况下将“绕过”第二个值。对于运算符or,情况亦如此。在表达式x or y中,如果x为真,就返回x,否则返回y。(你明白这样做合理的原因吗?)请注意,这意味着位于布尔运算符后面的代码(如函数调用)可能根本不会执行。像下面这样的代码就利用了这种行为:
name = input(‘Please enter your name: ‘) or ‘’
如果没有输入名字,上述or表达式的结果将为’’。在很多情况下,你都宁愿使用条件表达式,而不耍这样的短路花样。不过前面这样的语句确实有其用武之地。

5.5.4 一些有用的迭代工具
  1. 并行迭代
  • zip: 将两个序列“缝合”起来,并返回一个由元组组成的序列。可使用list将其转换为列表。当序列的长度不同时,函数zip将在最短的序列用完后停止“缝合”。
list(zip(name, ages))
for name, age in zip(names, ages):
	print(name, 'is', age, 'years old')
  1. 迭代时获取索引
    例如:替换一个字符串列表中所有包含子串’xxx’的字符串。
for string in strings:
	if 'xxx' in string:
		index = strings.index(string)  #在字符串中查找字符串
		strings[index] = '[censored]'

这可行,但替换前的搜索好像没有必要。另外,如果没有替换,搜索返回的索引可能不对(即返回的是该字符串首次出现处的索引)。下面是一种更佳的解决方案:

index = 0
for string in strings: 
	 if 'xxx' in string: 
		strings[index] = '[censored]' 
	 index += 1

这个解决方案虽然可以接受,但看起来也有点笨拙。另一种解决方案是使用内置函数enumerate。

for index, string in enumerate(strings):
 if 'xxx' in string: 
 strings[index] = '[censored]'
  1. 反向迭代和排序后再迭代
    reversed()和sorted()。它们类似于列表方法reverse和sort,但可用于任何序列或可迭代的对象,且不就地修改对象,而是返回反转和排序后的版本。
>>> sorted([4, 3, 6, 8, 3]) 
[3, 3, 4, 6, 8] 
>>> 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'] 
>>> ''.join(reversed('Hello, world!')) 
'!dlrow ,olleH' 

请注意,sorted返回一个列表,而reversed像zip那样返回一个更神秘的可迭代对象。你不能对它执行索引或切片操作,也不能直接对它调用列表的方法。要执行这些操作,可先使用list对返回的对象进行转换。
提示 要按字母表排序,可先转换为小写。为此,可将sort或sorted的key参数设置为str.lower。例如,

>>> sorted("aBc", key=str.lower)
>>> ['a', 'B', 'c']
5.5.5 调出循环
  1. break
  2. continue
  3. while True/break

5.6 简单推导

列表推导是一种从其他列表创建列表的方式

>>> [x*x for x in range(10) if x   3 == 0] %  
[0, 9, 36, 81] 
# 还可添加更多的for部分。 
>>> [(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)] 

5.7 del pass、exec和eval

警告 本节介绍如何执行存储在字符串中的Python代码,这样做可能带来严重的安全隐患。如果将部分内容由用户提供的字符串作为代码执行,将无法控制代码的行为。在网络应用程序,如第15章将介绍的通用网关接口(CGI)脚本中,这样做尤其危险。

5.8 本章介绍的新函数

函 数描 述
chr(n)返回一个字符串,其中只包含一个字符,这个字符对应于传入的顺序值n(0 ≤n < 256)
eval(source[,globals[,locals]])计算并返回字符串表示的表达式的结果
exec(source[, globals[, locals]])将字符串作为语句执行
enumerate(seq)生成可迭代的索引-值对
ord©接受一个只包含一个字符的字符串,并返回这个字符的顺序值(一个整数)
range([start,] stop[, step])创建一个由整数组成的列表
reversed(seq)按相反的顺序返回seq中的值,以便用于迭代
sorted(seq[,cmp][,key][,reverse])返回一个列表,其中包含seq中的所有值且这些值是经过排序的
xrange([start,] stop[, step])创建一个用于迭代的xrange对象
zip(seq1, seq2,…)创建一个适合用于并行迭代的新序列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔚蓝慕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值