1. 输入与输出

1.1 输入

默认情况下,Python input() 读取字符串类型

1.1.1 输入一个,需要转变类型

1
n = int(input())

1.1.2 输入两个数据,以空格隔开

1
2
# split() 将输入字符串以空格分割,分别赋予 a 和 b,赋值之前进行了 int() 类型转换
a, b = map(int, input().split())

1.1.3 输入多个同类型数据,以空格隔开

1
2
# list() 将 map 类型转变为 list 类型数据
l = list(map(int, input().split()))

1.1.4 先输入 n,再输入 n 行数据

1
2
3
4
5
6
7
8
n = int(input())
# 读入字符串
for i in range(n):
s = input()
# 读入列表
l = []
for i in range(n):
l.append(input())

1.1.5 输入数据,直到输入 0 截止

1
2
3
4
5
6
7
8
9
while True:
# 读入 n 之后立刻判断,避免执行后续代码
n = int(input())
if n == 0:
break
l = []
for i in range(n):
l.append(input())
print(l)

1.1.6 读入数据直到没有输入为止

1
2
3
4
5
6
7
from sys import stdin
for line in stdin:
line = line.strip()
if not line:
break
a, b = line.split()
print(a, b)

1.2. 输出

默认情况下,Python print() 输出包含换行

1.2.1 输出一个变量

1
2
a = 123
print(a)

1.2.2 在一行内输出列表的值,以空格间隔

1
2
3
l = [1, 2, 3]
for x in l:
print(x, end = " ")

1.2.3 简单变量字符串格式化

1
2
3
4
5
6
7
8
name = 'Mike'
age = 18
# 简单格式化
print(name + '\'s age is ' + str(age))
# 使用 % 格式化
print("%s's age is %d" % (name, age))
# 使用 f-string 格式化
print(f"{name}'s age is {age}")

1.2.4 复杂变量格式化

1
2
3
4
5
6
7
8
9
10
price = 1888
amount = 100

# 计算平均值,保留一位小数

# 使用 % 格式化
print("The average price of these %d pairs of pants is $%.1f" % (amount, price / amount))
# 使用 f-string 格式化
# 注意 {price / amount :.1f} 中 `:` 后面不能有空格,否则会输出多余空格,但前面可以有空格
print(f"The average price of these {amount} pairs of pants is ${price / amount : .1f}")

2. Python 基础

2.1 基础数据类型

Python 中常见数据类型如下:

  • Number(数字)
  • String(字符串)
  • bool (布尔类型)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

Python3 的六个标准数据类型中分为两种:

  • 不可变数据(3 个):Number(数字),String(字符串),Tuple(元组)
  • 可变数据(3 个):List(列表),Dictionary(字典),Set(集合)

2.1.1 Number(数字)

Python3 中 Number 包括 int、float、bool((・o・)ノ Yes!!,bool 也是 Number 类型的一种)、complex(复数)

int 类型在 Python3 中没有大小限制,可以当作 Long 类型使用,所以 Python3 没有 Python2 中的 Long 类型

float 类型可以使用科学计数法表示,如 1.23e91.23e-9

bool 类型只有两个值:TrueFalse

complex 类型用 a + bj 表示,a 是实部,b 是虚部

1
2
3
4
5
6
a = 2147483649
b = 1.23e9
c = True
d = 1 + 2j
e = 3 + 4j
print(a, b, c, d * e)

2.1.2 String(字符串)

Python 中字符串用单引号 '' 或双引号 "" 包围,三引号 ''' '''""" """ 可以用来表示多行字符串

字符串可以使用 + 连接,* 重复

字符串可以使用 [] 访问,[:] 截取

字符串的截取方式如下:

  • s[1] 取下标为 1 的字符
  • s[1:4] 取下标为 1 到 4 的字符
  • s[1:] 取下标为 1 到最后的字符
  • s[:4] 取下标为 0 到 4 的字符
  • s[-1] 取最后一个字符
  • s[-4:-1] 取倒数第 4 到倒数第 1 个字符

字符串的常用方法如下:

  • len(s) 返回字符串长度
  • s.strip() 去除字符串两端空格
  • s.lstrip() 去除字符串左端空格
  • s.rstrip() 去除字符串右端空格
  • s.lower() 将字符串转换为小写
  • s.upper() 将字符串转换为大写
  • s.replace(old, new) 将字符串中的 old 替换为 new
  • s.split() 以空格分割字符串
  • s.split(',') 以逗号分割字符串
  • s.find(sub) 查找子字符串 sub,返回下标,找不到返回 -1
  • s.index(sub) 查找子字符串 sub,返回下标,找不到抛出异常
  • s.count(sub) 统计子字符串 sub 出现次数
  • s.startswith(sub) 判断字符串是否以 sub 开头
  • s.endswith(sub) 判断字符串是否以 sub 结尾
  • s.isdigit() 判断字符串是否只包含数字
  • s.isalpha() 判断字符串是否只包含字母
  • s.isalnum() 判断字符串是否只包含数字和字母
1
2
3
4
s = 'Hello, World!'
print(s[1], s[1:4], s[1:], s[:4], s[-1], s[-4:-1])
print(len(s), s.strip(), s.lstrip(), s.rstrip(), s.lower(), s.upper(), s.replace('o', '0'))
print(s.split(), s.split(','), s.find('o'), s.index('o'), s.count('o'), s.startswith('Hello'), s.endswith('World!'), s.isdigit(), s.isalpha(), s.isalnum())

2.1.3 List(列表)

Python 中列表是有序的,可以包含任意类型的数据,用 [] 包围,用 , 分隔

列表的截取方式与字符串类似

列表的常用方法如下:

  • len(l) 返回列表长度
  • l.append(x) 在列表末尾添加元素 x
  • l.insert(i, x) 在列表下标 i 处插入元素 x
  • l.pop() 删除列表最后一个元素
  • l.pop(i) 删除列表下标 i 处的元素
  • l.remove(x) 删除列表中第一个出现的元素 x
  • l.clear() 清空列表
  • l.index(x) 返回元素 x 在列表中的下标,找不到抛出异常
  • l.count(x) 返回元素 x 在列表中出现的次数
  • l.sort() 对列表进行排序
  • l.reverse() 对列表进行反转
  • l.copy() 复制列表

经常使用的操作列表的方法还有切片:

  • print(l[2: 5]) 截取列表中下标 2 到 5 的元素
  • print(l[2:]) 截取列表中下标 2 到最后的元素
  • print(l[:5]) 截取列表中下标 0 到 5 的元素
  • print(l[-1]) 截取列表中最后一个元素
  • print(l[-4: -1]) 截取列表中倒数第 4 到倒数第 1 个元素
1
2
3
l = [1, 2, 3, 4, 5]
print(l[1], l[1:4], l[1:], l[:4], l[-1], l[-4:-1])
print(len(l), l.append(6), l.insert(0, 0), l.pop(), l.pop(0), l.remove(3), l.clear(), l.index(2), l.count(2), l.sort(), l.reverse(), l.copy())

2.1.4 Tuple(元组)

Python 中元组是有序的,可以包含任意类型的数据,用 () 包围,用 , 分隔

元组的截取方式与字符串类似

元组的常用方法如下:

  • len(t) 返回元组长度
  • t.count(x) 返回元素 x 在元组中出现的次数
  • t.index(x) 返回元素 x 在元组中的下标,找不到抛出异常
1
2
3
t = (1, 2, 3, 4, 5)
print(t[1], t[1:4], t[1:], t[:4], t[-1], t[-4:-1])
print(len(t), t.count(2), t.index(2))

2.1.5 Set(集合)

Python 中集合是无序的,不包含重复元素,用 {} 包围,用 , 分隔

集合的常用方法如下:

  • len(s) 返回集合长度
  • x in s 判断元素 x 是否在集合中
  • s.add(x) 向集合中添加元素 x
  • s.remove(x) 删除集合中元素 x,找不到抛出异常
  • s.discard(x) 删除集合中元素 x,找不到不抛出异常
  • s.pop() 删除集合中任意一个元素
  • s.clear() 清空集合
1
2
s = {1, 2, 3, 4, 5}
print(1 in s, 6 in s, len(s), s.add(6), s.remove(6), s.discard(6), s.pop(), s.clear())

2.1.6 Dictionary(字典)

Python 中字典是无序的,包含键值对,用 {key: value} 包围,用 , 分隔

字典的常用方法如下:

  • len(d) 返回字典长度
  • d[key] 返回键 key 对应的值
  • d[key] = value 设置键 key 对应的值为 value
  • key in d 判断键 key 是否在字典中
  • d.keys() 返回字典所有键
  • d.values() 返回字典所有值
  • d.items() 返回字典所有键值对
  • d.get(key) 返回键 key 对应的值,找不到返回 None
  • d.get(key, default) 返回键 key 对应的值,找不到返回 default
1
2
d = {'a': 1, 'b': 2, 'c': 3}
print(d['a'], d['b'], d['c'], len(d), 'a' in d, 'd' in d, d.keys(), d.values(), d.items(), d.get('a'), d.get('d'), d.get('d', 0))

2.2 函数

2.2.1 函数的定义、调用和参数

Python 中函数使用 def 关键字定义,使用 return 返回值

函数的参数可以有默认值,调用函数时可以不传递默认值参数

函数的参数可以是位置参数,也可以是关键字参数,关键字参数必须在位置参数之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def add(a, b):
return a + b

def add_default(a, b = 1):
return a + b

def add_keyword(a, b = 1, c = 2):
return a + b + c

print(add(1, 2), add_default(1), add_keyword(1), add_keyword(1, c = 3), add_keyword(1, 2, 3))

# 位置参数和关键字参数混合使用,位置参数必须在关键字参数之前
def add_mix(a, b, c = 1):
return a + b + c

print(add_mix(1, 2), add_mix(1, 2, 3))

2.2.2 递归函数

递归函数是在函数内部调用函数自身

递归函数必须有一个结束条件,否则会导致无限递归

以计算阶乘为例,比如若要计算 6 的阶乘,可以计算 5 的阶乘,然后再乘以 6,而要计算 5 的阶乘,可以先计算 4 的阶乘,然后再乘以 5,以此类推,递归函数的结束条件是 1 的阶乘是 1

1
2
3
4
5
6
7
def factorial(n):
# 递归结束条件
if n == 1:
return 1
return n * factorial(n - 1)

print(factorial(6))

2.2.3 匿名函数

Python 使用 lambda 关键字定义匿名函数,匿名函数没有函数名

匿名函数只能有一个表达式,表达式的结果就是返回值

1
2
f = lambda x, y: x + y
print(f(1, 2))

2.3 迭代器

2.3.1 迭代器和可迭代对象

迭代器是一个可以记住遍历位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束

迭代器有两个基本方法:iter()next()

字符串、列表或元组等都是可迭代对象,可以使用 iter() 方法将其转换为迭代器

1
2
3
4
5
6
7
8

l = [1, 2, 3, 4, 5]
it = iter(l)
print(next(it), next(it), next(it), next(it), next(it))

s = 'Hello, World!'
it = iter(s)
print(next(it), next(it), next(it), next(it), next(it))

2.3.2 生成器

生成器是一种特殊的迭代器,可以使用 yield 关键字定义生成器函数

生成器函数返回一个生成器对象,生成器对象是一个迭代器

生成器函数每次调用 next() 方法时执行,直到遇到 yield 语句返回,下次调用 next() 方法时从上次 yield 语句处继续执行

1
2
3
4
5
6
7
8
9
def fibonacci(n):
a, b, count = 0, 1, 0
while count < n:
yield a
a, b = b, a + b
count += 1

f = fibonacci(5)
print(next(f), next(f), next(f), next(f), next(f))

3. 函数式编程

3.1 高阶函数

3.1.1 map() 函数

map() 函数接收两个参数,一个是函数,一个是可迭代对象,map() 将传入的函数依次作用到序列的每个元素,并返回一个迭代器

1
2
3
4
5
6
def f(x):
return x * x

l = [1, 2, 3, 4, 5]
m = map(f, l)
print(list(m))

3.1.2 reduce() 函数

reduce() 函数接收两个参数,一个是函数,一个是可迭代对象,reduce() 将传入的函数依次作用到序列的每个元素,每次计算的结果继续和下一个元素做累积计算

1
2
3
4
5
6
7
8
from functools import reduce

def f(x, y):
return x + y

l = [1, 2, 3, 4, 5]
r = reduce(f, l)
print(r)

3.1.3 filter() 函数

filter() 函数接收两个参数,一个是函数,一个是可迭代对象,filter() 将传入的函数依次作用到序列的每个元素,返回值为 True 的元素组成一个迭代器

1
2
3
4
5
6
def f(x):
return x % 2 == 0

l = [1, 2, 3, 4, 5]
f = filter(f, l)
print(list(f))

案例·用 filter() 函数求素数

1
2
3
4
5
6
7
8
9
def isprime(n):
if n <= 1:
return False
for i in range(2, int(n ** 0.5 + 1)):
if n % i == 0:
return False
return True
l = list(filter(isprime, range(20)))
print(l)

3.1.4 sorted() 函数

sorted() 函数接收三个参数,一个是可迭代对象,一个是 key 函数,一个是 reverse 参数,sorted() 函数将传入的可迭代对象排序后返回一个新的列表

key 函数用来指定排序的关键字; reverse 参数用来指定排序的顺序, 默认为 False,表示升序,True 表示降序

1
2
3
4
l = [1, 3, 2, 5, 4]
print(sorted(l))
print(sorted(l, reverse = True))
print(sorted(l, key = lambda x: -x))

案例·用 sorted() 函数双值排序

1
2
l = [(1, 2), (3, 1), (2, 3), (5, 4), (4, 5)]
print(sorted(l, key = lambda x: (x[0], -x[1])))