任何简单或复杂的算法都可以由顺序结构、选择结构和循环结构这是那种基本结构组合而成。

  • 顺序结构:程序从上到下顺序的执行代码,中间没有任何判断和跳转,直到程序结束
  • 选择结构:程序根据判断条件的布尔值选择性的执行部分代码
  • 循环结构:程序根据循环条件反复执行某段代码,直到不满足循环条件为止。

代码块

代码块是一组相关语句的集合。
在Python中,代码块开始于冒号,代码块中的所有行(不包括自代码块)都要缩进相同数量的空格,通常缩进4个空格。
不要忘记缩进,也不要添加不必要的缩进。

选择结构

if语句

语法格式:

if 判断条件:
    执行语句……
else:
    执行语句……

Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false。

其中"判断条件"成立时(非零),则执行后面的语句,而执行内容可以多行,以缩进来区分表示同一范围。

else 为可选语句,当需要在条件不成立时执行内容则可以执行相关语句。
例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
# 例1:if 基本用法
 
flag = False
name = 'luren'
if name == 'python':         # 判断变量是否为 python 
    flag = True              # 条件成立时设置标志为真
    print 'welcome boss'     # 并输出欢迎信息
else:
    print name               # 条件不成立时输出变量名称

对象的布尔值

所有对象都有一个布尔值,可以调用内置函数bool得到对象的布尔值:
这些对象的布尔值为False:False、数值零、None、空字符串、空列表、空元组、空字典、空集合。
所有对象都可被直接用作布尔值,解释器会自动调用内置函数bool进行转换

if 18:
    print(18, True)
# 18 True

if 'Python':
    print('Python', True)
# Python True

条件表达式

条件表达式是包含if-else语句的表达式,它类似于C语言中的三目条件运算符。
语法:
x if 判断条件 else y
解释:
如果判断条件的布尔值为True,条件表达式的返回值为x;否则,条件表达式的返回值为y。
例:

score = 88
result = '及格了' if score >= 60 else '不及格'
print(result)

if score >= 60:
    result = '及格了'
else:
    result = '不及格'
print(result)

返回结果如下:

及格了
及格了

在一个条件表达式内可以嵌套另外一个条件表达式:

a = 6
b = 8
print('a大于b' if a > b else ('a小于b' if a < b else 'a等于b'))

返回结果如下:

a小于b

循环结构

while语句

语法:

初始化部分
while 循环条件:
    循环体

解释:

  • 初始化部分:用于设置循环的初始条件,比如循环控制变量的初始值。
  • 循环条件:每次循环都要判断循环条件的布尔值,以决定继续循环还是终止循环。
  • 循环体:这是循环操作的主体内容,可以是一条语句,也可以是多条语句。循环体中的某些语句用于改变循环控制变量的值,从而改变循环条件的布尔值。
  • 执行流程如下:
    1. 执行完一次初始化部分之后,返回判断循环条件的布尔值。
    2. 如果循环条件的布尔值为False,则终止循环;
    3. 如果循环条件的布尔值为True,则执行循环体,执行完循环体后再次判断循环条件的布尔值。

例:

i = 1
while i < 11:
    print(i)
    i += 1

应该确保让循环条件的布尔值在某一时刻变为False,以避免while语句陷入死循环

有时候循环条件可能不太容易确定,需要在循环体中才能确定是否要退出循环,在这种情况下:可以使用while-True-break结构,也就是说,通过while True构造一个无限循环,在循环体中满足某个条件时通过break退出循环。

while 1:
    word = input('请输入一个单词:')
    if not word: break
    print('输入的单词是:', word)

for-in语句

for-in语句专门用于遍历序列、字典和集合等类型的对象。
其中,遍历指的是:把对象的所有元素依次访问一遍。每访问一个元素,称之为一次迭代。因此可以使用for-in语句遍历的对象又被成为可迭代对象。
语法:

for 自定义变量 in 要遍历的可迭代对象:
    循环体

说明:
循环体对应的代码必须要缩进。
如果循环体内不需要访问自定义的变量,可以将自定义的变量替代为下划线_。
执行流程:

  1. 反复判断是否遍历完可迭代对象中的所有元素;
  2. 如果已经遍历完可迭代对象中的所有元素,则终止循环;
  3. 如果没有遍历完可迭代对象中的所有元素,则自定义的变量自动被赋予当前迭代的元素值,然后执行循环体,执行完循环体后再次判断是否遍历完可迭代对象中的所有元素。

当迭代次数已知时,推荐使用for-in语句;当迭代次数未知时,推荐使用while语句。

遍历range、列表、元组和字符串等序列

for number in range(1, 4):
    print(number)

for _ in range(1, 4):
    print('Hello')

for number in [1, 2, 3]:
    print(number)

for number in (1, 2, 3):
    print(number)

for char in '123':
    print(char)

在遍历序列的过程中,如果需要对序列进行修改,最好先通过切片操作生成一份序列的拷贝。

words = ['Jave', 'Python', 'Kotlin', 'Swift', 'Go']
for word in words[:]:
    if len(word) < 5:
        words.remove(word)
print(words)    # ['Python', 'Kotlin', 'Swift'

遍历集合和字典

s = {2, 3, 1}
for number in s:
    print(number)

for number in sorted(s):
    print(number)

d= {'Fruits': 86, 'Books': 88, 'Videos': 83}
for elem in d:
    print(elem)

for key in d.keys():
    print(key)

for value in d.values():
    print(value)

for key, value in d.items():
    print(key, '->', value)

带索引的序列遍历

第一种方式:

L = ['Java', 'Python', 'Swift', 'Kotlin']
index = 0
for item in L:
    print('L[{}] = {}'.format(index, item))
    index += 1

返回结果:

L[0] = Java
L[1] = Python
L[2] = Swift
L[3] = Kotlin

第二种方式:

L = ['Java', 'Python', 'Swift', 'Kotlin']
for index in range(len(L)):
    print('L[{}] = {}'.format(index, L[index]))
    index += 1

第三种方式:

L = ['Java', 'Python', 'Swift', 'Kotlin']
index = 0
while index < len(L):
    print('L[{}] = {}'.format(index, L[index]))
    index += 1

第四种方式:

L = ['Java', 'Python', 'Swift', 'Kotlin']
# 调用内置函数enumerate将要遍历的序列转换为enumerate对象
print(enumerate(L)) # <enumerate object at 0x00000263D8837080>
# 为了清楚地表示返回的enumerate对象所表示的内存,可以将enumerate对象转换成列表
print(list(enumerate(L)))   # [(0, 'Java'), (1, 'Python'), (2, 'Swift'), (3, 'Kotlin')]
# 调用内置函数enumerate时,可以通过第二个参数指定索引的起始值。
print(list(enumerate(L, 1)))    # [(1, 'Java'), (2, 'Python'), (3, 'Swift'), (4, 'Kotlin')]
# 既可以遍历enumerate对象转换后的列表,也可以直接遍历enumerate对象。
for index, item in list(enumerate(L)):
    print('L[{}] = {}'.format(index, L[index]))

for index, item in enumerate(L):
    print('L[{}] = {}'.format(index, L[index]))

break-else结构

在执行while语句或for-in语句时,如果循环正常结束,也就是说如果没有执行循环体中的break语句从而提前退出循环,有时可能想在循环正常结束后执行某些操作。
为了判断循环是否正常结束,可以使用一个布尔变量,在循环开始前就将布尔变量的值设置为False,如果执行了循环体中的break语句从而提前退出循环,那就将布尔变量的值设置为True。
最后,在while语句或for-in语句的后面使用if语句判断布尔变量的值,以判断循环是否正常结束。

isBreak = False
n = 0
while n < 5:
    if n == 6:
        isBreak = True
        break
    n += 1
if not isBreak:
    print('循环正常结束,没有执行循环体中的break语句')

上述的解决方案还有更好的替代。 Python为循环语句提供了break-else结构,也就是说,可以在while语句或for-in语句的后面添加else从句,这样,如果没有执行循环体中的break语句从而提前退出循环,就会执行else从句。

n = 0
while n < 5:
    if n == 6:
        break
    n += 1
else:
    print('循环正常结束,没有执行循环体中的break语句')

break和continue

在while语句或for-in语句的循环体中,除了可以使用break语句之外,还可以使用continue语句,两者的区别在于:

  • break:表示“断路”,用于结束整个循环。
  • continue:表示“短路”,用于结束当前迭代,继续下一个迭代。

在嵌套循环中,break和continue默认只作用于当前循环。

for i in range(1, 5):
    if i == 3:
        break
    print('i =', i)

for i in range(1, 5):
    if i == 3:
        continue
    print('i=', i)

for i in range(1, 4):
    for j in range(1, 4):
        if i == j:
            break
        print('i = ', i, 'j = ', j)

for i in range(1, 4):
    for j in range(1, 4):
        if i == j:
            continue
        print('i = ', i, 'j = ', j)

并行遍历

有时可能需要同时遍历多个可迭代对象,也就是并行遍历,例如:列表names中存放姓名,列表ages中存放对应的年龄。如果想同时遍历这两个列表,打印出所有的姓名及对应的年龄,可以这样实现:

names = ['Jack', 'Mike', 'Tom']
ages = [16, 32, 43]
for i in range(len(names)):
    print(names[i], '的年龄是:', ages[i])
    
# 返回结果如下
Jack 的年龄是: 16
Mike 的年龄是: 32
Tom 的年龄是: 43

上述的解决方案有更好的替代,如果需要同时遍历多个可迭代对象,可以调用内置变量zip将多个可迭代对象打包压缩成zip对象。

names = ['Jack', 'Mike', 'Tom']
ages = [16, 32, 43]

print(zip(names, ages))

# 问了清楚的表示返回的zip对象所表示的内容,可以将zip对象转换成列表
# 列表中的元素都是元组,元组中的第i个元素来自调用zip时的第i个参数。

print(list(zip(names, ages)))

# 既可以遍历zip对象转换后的列表,也可以直接遍历zip对象
for name, age in list(zip(names, ages)):
    print(name, '的年龄是:', age)

for name, age in zip(names, ages):
    print(name, '的年龄是:', age)

# 调用内置函数zip将多个可迭代对象进行打包压缩时,如果两个可迭代对象的长度不同。那么较长的可迭代对象会被截断。
# 可以使用*对zip对象解压缩
x = [1, 2, 3]
y = [4, 5, 6]
print(list(zip(x, y)))
print(list(zip(*zip(x, y))))

x2, y2 = zip(*zip(x, y))
print(list(x2))
print(list(y2))

返回结果如下:

<zip object at 0x000002AE59D66100>
[('Jack', 16), ('Mike', 32), ('Tom', 43)]
Jack 的年龄是: 16
Mike 的年龄是: 32
Tom 的年龄是: 43
Jack 的年龄是: 16
Mike 的年龄是: 32
Tom 的年龄是: 43
[(1, 4), (2, 5), (3, 6)]
[(1, 2, 3), (4, 5, 6)]
[1, 2, 3]
[4, 5, 6]

遍历可迭代对象

内置函数map

第一个参数指定函数名,第二个参数指定可迭代对象。
调用内置函数map后,会使用指定的函数名作用于指定的可迭代对象的每个元素,然后生成新的可迭代对象。

result = map(ord, 'abcd')
print(result)
print(list(result))

# str.upper表示类str的方法upper,也就是字符串的方法upper
result = map(str.upper, 'abcd')
print(result)
print(list(result))

返回结果如下:

<map object at 0x0000019E90AB5390>
[97, 98, 99, 100]
<map object at 0x0000019E90E1FD90>
['A', 'B', 'C', 'D']

内置函数filter

第一个参数指定函数名,第二个参数指定可迭代对象。
调用内置函数filter后,会使用指定的函数名作用于指定的可迭代对象的每个元素,过滤掉函数返回值为False的相关元素,然后生成新的可迭代对象。

result = filter(str.isalpha, '123abc')
print(result)       # <filter object at 0x00000171F5825390>
print(list(result)) # ['a', 'b', 'c']

星霜荏苒 居诸不息