本文整理了Python入门的一些小练习题目和相应的题解,包括图像绘制、利用爬虫爬取网页数据等等。


1.根据半径r计算圆的面积

1
2
3
4
# 计算圆的面积
r = float(input())
area = 3.1415926*r*r
print('{:.2f}'.format(area))

2.绘制多个同切圆

1
2
3
4
5
6
7
8
# 绘制多个同切圆
import turtle # 导入turtle模块
turtle.pensize(2) # 设置笔刷宽度
turtle.circle(10) # 绘制半径为10的圆
turtle.circle(30)
turtle.circle(50)
turtle.circle(100)
turtle.done() # 保持绘图界面

3.绘制一个五角星

1
2
3
4
5
6
7
8
from turtle import *
color('red', 'yellow')
begin_fill()
for i in range(5):
fd(200)
rt(144)
end_fill()
done()

4.摄氏温度与华氏温度相互转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# is_number函数可以判断一个字符串是否能被转换为一个数
def is_number(s):
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
return False


TempStr = input('请输入带有符号的温度值:')
if TempStr[-1] in ['F', 'f'] and is_number(TempStr[0:-1]):
C = (eval(TempStr[0:-1])-32)/1.8 # eval() 函数用来执行一个字符串表达式,并返回表达式的值
print('转换后的温度是{:.2f}C'.format(C))
elif TempStr[-1] in ['C', 'c'] and is_number(TempStr[0:-1]):
F = 1.8*eval(TempStr[0:-1])+32
print('转换后的温度是{:.2f}F'.format(F))
else:
print('输入格式错误')

5.获得用户输入的一个正整数输入,输出该数字对应的中文字符表示

  • 参考题解1
1
2
3
4
s = input()
array = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
for i in s:
print(array[int(i)], end='')
  • 参考题解2
1
2
3
4
template = "零一二三四五六七八九"
s = input()
for c in s:
print(template[eval(c)], end="")

6.输入正整数n,计算1+2+3+…+n

1
2
3
4
5
ans = 0
n = int(input())
for i in range(1, n+1):
ans += i
print(ans)

7.输入正整数n,计算n的阶乘

  • 普通循环形式
1
2
3
4
5
ans = 1
n = int(input())
for i in range(1, n+1):
ans *= i
print(ans)
  • 自定义函数形式
1
2
3
4
5
6
7
8
9
def fact(n):
res = 1
for i in range(1, n+1):
res *= i
return res


n = int(input())
print(fact(n))
  • 递归形式
1
2
3
4
5
6
7
8
9
def fact(n):
if n == 0 or n == 1:
return 1
else:
return n*fact(n-1)


n = int(input())
print(fact(n))

8.根据输入的参数值,以不同方式打印输出”Hello World”

  1. 如果输入值是0,直接输出”Hello World”‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬
  2. 如果输入值大于0,以两个字符一行方式输出”Hello World”(空格也是字符)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬
  3. 如果输入值小于0,以垂直方式输出”Hello World”
  • 参考题解1
1
2
3
4
5
6
7
8
9
10
11
12
s = 'Hello World'
n = int(input())
if n == 0:
print(s)
elif n > 0:
i = 0
while(i < len(list(s))):
print(s[i:i+2:1])
i += 2
else:
for i in s:
print(i)
  • 参考题解2
1
2
3
4
5
6
7
8
n = eval(input())
if n == 0:
print("Hello World")
elif n > 0:
print("He\nll\no \nWo\nrl\nd")
else:
for c in "Hello World":
print(c)

9.运算数学表达式

获得用户输入的一个字符串,格式如下:‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬ M OP N‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬ 其中,M和N是任何数字,OP代表一种操作,表示为如下四种:+, -, *, /(加减乘除)‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬,根据OP,输出M OP N的运算结果,统一保存小数点后2位。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬注意:M和OP、OP和N之间可以存在多个空格,不考虑输入错误情况。

1
2
s = input()
print("{:.2f}".format(eval(s)))

10.随笔画

(1)画房子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import turtle
turtle.pencolor('purple')
turtle.goto(50, 100)
turtle.goto(-150, 100)
turtle.goto(-200, 0)
turtle.goto(-200, -200)
turtle.goto(0, -200)
turtle.goto(0, 0)
turtle.goto(-200, 0)
turtle.goto(100, 0)
turtle.goto(50, 100)
turtle.goto(100, 0)
turtle.goto(100, -200)
turtle.goto(0, -200)
turtle.goto(-50, -200)
turtle.goto(-50, -100)
turtle.goto(-90, -100)
turtle.goto(-90, -200)
turtle.done()

效果简单,暂不展示。

(2)画玫瑰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import turtle

# 设置初始位置
turtle.penup()
turtle.left(90)
turtle.fd(200)
turtle.pendown()
turtle.right(90)

# 花蕊
turtle.fillcolor("red")
turtle.begin_fill()
turtle.circle(10, 180)
turtle.circle(25, 110)
turtle.left(50)
turtle.circle(60, 45)
turtle.circle(20, 170)
turtle.right(24)
turtle.fd(30)
turtle.left(10)
turtle.circle(30, 110)
turtle.fd(20)
turtle.left(40)
turtle.circle(90, 70)
turtle.circle(30, 150)
turtle.right(30)
turtle.fd(15)
turtle.circle(80, 90)
turtle.left(15)
turtle.fd(45)
turtle.right(165)
turtle.fd(20)
turtle.left(155)
turtle.circle(150, 80)
turtle.left(50)
turtle.circle(150, 90)
turtle.end_fill()


# 花瓣1
turtle.left(150)
turtle.circle(-90, 70)
turtle.left(20)
turtle.circle(75, 105)
turtle.setheading(60)
turtle.circle(80, 98)
turtle.circle(-90, 40)

# 花瓣2
turtle.left(180)
turtle.circle(90, 40)
turtle.circle(-80, 98)
turtle.setheading(-83)


# 叶子1
turtle.fd(30)
turtle.left(90)
turtle.fd(25)
turtle.left(45)
turtle.fillcolor("green")
turtle.begin_fill()
turtle.circle(-80, 90)
turtle.right(90)
turtle.circle(-80, 90)
turtle.end_fill()

turtle.right(135)
turtle.fd(60)
turtle.left(180)
turtle.fd(85)
turtle.left(90)
turtle.fd(80)


# 叶子2
turtle.right(90)
turtle.right(45)
turtle.fillcolor("green")
turtle.begin_fill()
turtle.circle(80, 90)
turtle.left(90)
turtle.circle(80, 90)
turtle.end_fill()

turtle.left(135)
turtle.fd(60)
turtle.left(180)
turtle.fd(60)
turtle.right(90)
turtle.circle(200, 60)
turtle.done()

效果:

玫瑰

(3)画一棵树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from turtle import *
from random import *
from math import *


def tree(n, l):
pd() # 下笔
# 阴影效果
t = cos(radians(heading() + 45)) / 8 + 0.25
pencolor(t, t, t)
pensize(n / 3)
forward(l) # 画树枝
if n > 0:
b = random() * 15 + 10 # 右分支偏转角度
c = random() * 15 + 10 # 左分支偏转角度
d = l * (random() * 0.25 + 0.7) # 下一个分支的长度
# 右转一定角度,画右分支
right(b)
tree(n - 1, d)
# 左转一定角度,画左分支
left(b + c)
tree(n - 1, d)
# 转回来
right(c)
else:
# 画叶子
right(90)
n = cos(radians(heading() - 45)) / 4 + 0.5
pencolor(n, n*0.8, n*0.8)
circle(3)
left(90)
# 添加0.3倍的飘落叶子
if(random() > 0.7):
pu()
# 飘落
t = heading()
an = -40 + random()*40
setheading(an)
dis = int(800*random()*0.5 + 400*random()*0.3 + 200*random()*0.2)
forward(dis)
setheading(t)
# 画叶子
pd()
right(90)
n = cos(radians(heading() - 45)) / 4 + 0.5
pencolor(n*0.5+0.5, 0.4+n*0.4, 0.4+n*0.4)
circle(2)
left(90)
pu()
# 返回
t = heading()
setheading(an)
backward(dis)
setheading(t)
pu()
backward(l) # 退回


bgcolor(0.5, 0.5, 0.5) # 背景色
ht() # 隐藏turtle
speed(0) # 速度,1-10渐进,0最快
tracer(0, 0)
pu() # 抬笔
backward(100)
left(90) # 左转90度
pu() # 抬笔
backward(300) # 后退300
tree(12, 100) # 递归7层
done()

效果:

树


11.获取星期字符串

1
2
3
weekStr = '一二三四五六日'
weekId = eval(input('请输入星期数字(1-7): '))
print('星期'+weekStr[weekId-1])

12.打印沙漏

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

1
2
3
4
5
*****
***
*
***
*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

  • 输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

  • 输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

  • 输入样例:
1
19 *
  • 输出样例:
1
2
3
4
5
6
*****
***
*
***
*****
2
  • 参考题解:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import math

def show(n, c):
for i in range(-(n-1), n):
print((n-1-abs(i))*' '+((abs(i)+1)*2-1)*c, end='')
print()


n, ch = input().split()
num = int(n)
ans = num
while(True):
if int(math.sqrt((num+1)/2)) == math.sqrt((num+1)/2):
t = int(math.sqrt((num+1)/2))
break
num -= 1

show(t, ch)
print(ans-2*t*t+1)

13.计算程序运行时间

1
2
3
4
5
6
import time
start = time.perf_counter()
for i in range(1234567):
t = i + 1
end = time.perf_counter()
print(end - start)

14.文本进度条

  • 多行
1
2
3
4
5
6
7
8
9
10
11
# 多行
import time
scale = 50
print('------执行开始------')
for i in range(scale+1):
a = '*' * i
b = '.' * (scale - i)
c = (i/scale)*100
print('{:^3.0f}%[{}->{}]'.format(c, a, b))
time.sleep(0.1)
print('------执行结束------')
  • 单行
1
2
3
4
5
6
7
8
9
10
11
12
13
# 单行
import time
scale = 50
print('执行开始'.center(scale//2, '-'))
start = time.perf_counter()
for i in range(scale + 1):
a = '*' * i
b = '.' * (scale - i)
c = (i/scale)*100
dur = time.perf_counter() - start
print('\r{:^3.0f}%[{}->{}]{:.2f}s'.format(c, a, b, dur), end='')
time.sleep(0.1)
print('\n'+'执行结束'.center(scale//2, '-'))

15.计算圆周率

  • 方法一

圆周率公式

1
2
3
4
5
pi = 0
N = 100
for k in range(N):
pi += 1/pow(16, k)*(4/(8*k+1)-2/(8*k+4)-1/(8*k+5)-1/(8*k+6))
print(pi)
  • 方法二(蒙特卡罗方法)
1
2
3
4
5
6
7
8
9
10
11
from random import random
from time import perf_counter
DARTS = 1000*1000
hits = 0.0
for i in range(1, DARTS+1):
x, y = random(), random()
dist = pow(x ** 2 + y ** 2, 0.5)
if dist <= 1.0:
hits += 1
pi = 4 * (hits/DARTS)
print(pi)

16.可变参数传递

1
2
3
4
5
6
7
8
9
10
11
def fact(n, *p):
res = 1
for i in range(1, n+1):
res *= i
for item in p:
res *= item
return res


# 相当于 10! * 2 * 3 * 5
print(fact(10, 2, 3, 5))

17.函数可以有多个返回值

1
2
3
4
5
6
7
8
9
def fact(n, m=1):
s = 1
for i in range(1, n+1):
s *= i
return s//m, n, m


a, b, c = fact(10, 5)
print(a, b, c)

18.局部变量和全局变量

1
2
3
4
5
6
7
8
9
10
11
12
13
n, s = 10, 100


def fact(n, m=1):
# fact()函数中使用global保留字
# 声明此处s是全局变量s
global s
for i in range(1, n+1):
s *= i
return s # 此处s指全局变量s


print(fact(n), s) # 此处全局变量s被函数修改
  • 局部变量为组合数据类型且未创建,等同于全局变量
1
2
3
4
5
6
7
8
9
10
11
ls = ['F', 'f']


def fun(a):
# 此处ls是列表类型,未真实创建,则等同于全局变量
ls.append(a)
return


fun('c') # 全局变量ls被修改
print(ls)
  • 局部变量为组合数据类型被真实创建,等同于局部变量
1
2
3
4
5
6
7
8
9
10
11
12
ls = ['F', 'f']


def fun(a):
ls = []
# 此处ls是列表类型,真实创建,则等同于局部变量
ls.append(a)
return


fun('c') # 全局变量ls未被修改
print(ls)

19.lambda函数

1
2
def f(x, y): return x+y
print(f(10, 15))

20.绘制七段数码管

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import turtle


def drawLine(draw):
turtle.pendown() if draw else turtle.penup()
turtle.fd(40)
turtle.right(90)


def drawDight(digit):
drawLine(True) if digit in [2, 3, 4, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 1, 3, 4, 5, 6, 7, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 2, 3, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 2, 6, 8] else drawLine(False)
turtle.left(90)
drawLine(True) if digit in [0, 4, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 2, 3, 5, 6, 7, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 1, 2, 3, 4, 7, 8, 9] else drawLine(False)
turtle.left(180)
turtle.penup()
turtle.fd(20)


def drawDate(data):
for i in data:
drawDight(int(i))


def main():
turtle.setup(800, 350, 200, 200)
turtle.penup()
turtle.fd(-300)
turtle.pensize(5)
drawDate('1234567890')
turtle.hideturtle()
turtle.done()


main()
  • 功能扩展:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import turtle
import time


def drawGap():
turtle.penup()
turtle.fd(5)


def drawLine(draw):
drawGap()
turtle.pendown() if draw else turtle.penup()
turtle.fd(40)
drawGap()
turtle.right(90)


def drawDight(digit):
drawLine(True) if digit in [2, 3, 4, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 1, 3, 4, 5, 6, 7, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 2, 3, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 2, 6, 8] else drawLine(False)
turtle.left(90)
drawLine(True) if digit in [0, 4, 5, 6, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 2, 3, 5, 6, 7, 8, 9] else drawLine(False)
drawLine(True) if digit in [0, 1, 2, 3, 4, 7, 8, 9] else drawLine(False)
turtle.left(180)
turtle.penup()
turtle.fd(20)


def drawDate(date):
turtle.pencolor('red')
for i in date:
if i == '-':
turtle.write('年', font=('Arial', 18, 'normal'))
turtle.pencolor('green')
turtle.fd(40)
elif i == '=':
turtle.write('月', font=('Arial', 18, 'normal'))
turtle.fd(40)
elif i == '+':
turtle.write('日', font=('Arial', 18, 'normal'))
else:
drawDight(int(i))


def main():
turtle.setup(800, 350, 200, 200)
turtle.penup()
turtle.fd(-300)
turtle.pensize(5)
drawDate(time.strftime('%Y-%m=%d+'))
turtle.hideturtle()
turtle.done()


main()

效果:

数码管日期


21.递归

  • 字符串反转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def rvs(s):
if s == '':
return s
else:
return rvs(s[1:])+s[0]


# 非递归形式:
'''
def rvs(s):
return s[::-1]
'''

s = 'abcdefg'
print(rvs(s))
  • 斐波那契数列
1
2
3
4
5
6
7
8
def fib(n):
if n == 1 or n == 2:
return 1
else:
return fib(n-1)+fib(n-2)


print(fib(20))
  • 汉诺塔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
count = 0


def hanoi(n, src, dst, mid):
global count
if n == 1:
print('{}->{}'.format(src, dst))
count += 1
else:
hanoi(n-1, src, mid, dst)
print('{}->{}'.format(src, dst))
count += 1
hanoi(n-1, mid, dst, src)


hanoi(3, 'A', 'C', 'B')
print(count)

22.绘制科赫曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import turtle


def koch(size, n):
if n == 0:
turtle.fd(size)
else:
for angle in [0, 60, -120, 60]:
turtle.left(angle)
koch(size/3, n-1)


def main():
turtle.setup(800, 400)
turtle.penup()
turtle.goto(-300, -50)
turtle.pendown()
turtle.pensize(2)
koch(600, 3) # 3阶科赫曲线
turtle.hideturtle()
turtle.done()


main()
  • 科赫雪花:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import turtle


def koch(size, n):
if n == 0:
turtle.fd(size)
else:
for angle in [0, 60, -120, 60]:
turtle.left(angle)
koch(size/3, n-1)


def main():
turtle.setup(600, 600)
turtle.penup()
turtle.goto(-200, 100)
turtle.pendown()
turtle.pensize()
level = 3
koch(400, level)
turtle.right(120)
koch(400, level)
turtle.right(120)
koch(400, level)
turtle.hideturtle()
turtle.done()


main()

23.利用集合进行去重

1
2
3
4
ls = ['p', 'y', 'p', 'y', 1, 2, 3, 2]
s = set(ls)
ans = list(s)
print(ans)

24.基本统计值计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def getNum():
nums = []
iNumStr = input('请输入数字(回车退出):')
while iNumStr != '':
nums.append(eval(iNumStr))
iNumStr = input('请输入数字(回车退出):')
return nums


def mean(numbers):
s = 0.0
for num in numbers:
s += num
return s / len(numbers)


def dev(numbers, mean):
sdev = 0.0
for num in numbers:
sdev = sdev + (num - mean) ** 2
return pow(sdev / (len(numbers)-1), 0.5)


def medium(numbers):
sorted(numbers)
size = len(numbers)
if size % 2 == 0:
med = (numbers[size//2-1] + numbers[size//2])/2
else:
med = numbers[size//2]
return med


n = getNum()
m = mean(n)
print('平均值:{}, 方差:{:.2f}, 中位数:{}.'.format(m, dev(n, m), medium(n)))

25.文本词频统计

  • 英文文本词频统计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def getText():
txt = open("hamlet.txt", "r").read()
txt = txt.lower() # 转小写
for ch in '!"#$%&()*+,-./:;<=>?@[\]^_`{|}~':
txt = txt.replace(ch, " ")
return txt


hamletTxt = getText()
words = hamletTxt.split()
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True) # 按键值对的第二个元素按从大到小的顺序排序
for i in range(10):
word, count = items[i]
print("{0:<10}{1:>5}".format(word, count))
  • 中文文本词频统计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import jieba
txt = open("threekingdoms.txt", "r", encoding="utf-8").read() # 这里的编码方式要根据文件选择
words = jieba.lcut(txt)
counts = {}
for word in words:
if len(word) == 1:
continue
else:
counts[word] = counts.get(word, 0) + 1
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True) # 按键值对的第二个元素按从大到小的顺序排序
for i in range(15):
word, count = items[i]
print("{0:<10}{1:>5}".format(word, count))
  • 《三国演义》人物出场频率统计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import jieba
# 这里的编码方式要根据文件选择
txt = open("threekingdoms.txt", "r", encoding="utf-8").read()
# 排除词库,根据运行结果人工不断进行优化,将不是人名的词语加入到本词库中
excludes = {"将军", "却说", "荆州", "二人", "不可", "不能", "如此"}
words = jieba.lcut(txt)
counts = {}
for word in words:
if len(word) == 1:
continue
elif word == "诸葛亮" or word == "孔明曰":
rword = "孔明"
elif word == "关公" or word == "云长":
rword = "关羽"
elif word == "玄德" or word == "玄德曰":
rword = "刘备"
elif word == "孟德" or word == "丞相曰":
rword = "曹操"
else:
rword = word
counts[rword] = counts.get(rword, 0) + 1
for word in excludes:
del counts[word]
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True) # 按键值对的第二个元素按从大到小的顺序排序
for i in range(15):
word, count = items[i]
print("{0:<10}{1:>5}".format(word, count))

26.判断素数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 判断整数n是否是素数
import math


def isprime(n):
if n < 2:
return False
else:
for i in range(2, int(math.sqrt(n)+1)):
if n % i == 0:
return False
return True


m, n = 1, 200
# m, n = map(int, input().split())
result = [i for i in range(m, n+1) if isprime(i)]
print(m, '到', n, '之间素数的个数为:', len(result))
print(result, end=' ')
print()

27.f.txt文件保存:“中国是个伟大的国家!”

1
2
3
4
tf = open("f.txt", "rt")  # 文本形式打开
# tf = open("f.txt", "rb") 二进制形式打开
print(tf.readline())
tf.close()

28.文件的全文本操作

  • 方法一
1
2
3
4
5
fname = input("请输入要打开的文件名称:")
fo = open(fname,"r")
txt = fo.read()
# 对全文txt进行处理
fo.close()
  • 方法二
1
2
3
4
5
6
7
fname = input("请输入要打开的文件名称:")
fo = open(fname, "r")
txt = fo.read(2)
while txt != "":
# 对txt进行处理
txt = fo.read(2)
fo.close()

29.逐行遍历文件

  • 方法一
1
2
3
4
5
fname = input("请输入要打开的文件名称:")
fo = open(fname, "r")
for line in fo.readlines():
print(line)
fo.close()
  • 方法二
1
2
3
4
5
fname = input("请输入要打开的文件名称:")
fo = open(fname, "r")
for line in fo:
print(line)
fo.close()
  • 方法三
1
2
3
4
5
6
7
file = open(fname, encoding="utf-8")
while True:
text = file.readline()
if not file:
break
print(text)
file.close()

30.文件的写入

1
2
3
4
5
6
7
fo = open("output.txt", "w+")
ls = ["中国", "法国", "美国"]
fo.writelines(ls)
fo.seek(0)
for line in fo:
print(line)
fo.close()

31.自动轨迹绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import turtle as t
t.title('自动轨迹绘制')
t.setup(800, 600, 0, 0)
t.pencolor('red')
t.pensize(5)
# 数据读取
datals = []
f = open("data.txt")
for line in f:
line = line.replace("\n", "")
datals.append(list(map(eval, line.split(","))))
f.close()
# 自动绘制
for i in range(len(datals)):
t.pencolor(datals[i][3], datals[i][4], datals[i][5])
t.fd(datals[i][0])
if datals[i][1]:
t.right(datals[i][2])
else:
t.left(datals[i][2])
t.done()

data.txt文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
300,0,144,1,0,0
300,0,144,0,1,0
300,0,144,0,0,1
300,0,144,1,1,0
300,0,144,0,1,1
300,0,144,1,0,1
300,0,144,0,0,0
184,0,72,0,0,0
184,0,72,0,0,0
184,1,72,1,0,1
184,1,72,0,0,0
184,1,72,0,0,0
184,1,72,0,0,0
184,1,72,0,0,0
184,1,720,0,0,0

32.一维数据的读入处理

  • 从空格分隔的文件中读入数据
1
2
3
4
5
# 中国 美国 日本 德国 法国 英国 意大利
txt = open(fname).read()
ls = txt.split()
f.close()
# ['中国', '美国', '日本', '德国', '法国', '英国', '意大利']
  • 从特殊字符分隔的文件中读入数据
1
2
3
4
5
# 中国$美国$日本$德国$法国$英国$意大利
txt = open(fname).read()
ls = txt.split('$')
f.close()
# ['中国', '美国', '日本', '德国', '法国', '英国', '意大利']

33.一维数据的写入处理

  • 以空格分隔写入
1
2
3
4
ls = ['中国', '美国', '俄罗斯']
f = open(fname, 'w')
f.write(' '.join(ls))
f.close()
  • 以特殊字符分隔写入
1
2
3
4
ls = ['中国', '美国', '俄罗斯']
f = open(fname, 'w')
f.write('$'.join(ls))
f.close()

34.二维数据的处理

  • 从csv格式的文件中读入数据
1
2
3
4
5
6
fo = open(fname)
ls = []
for line in fo:
line = line.replace("\n", "")
ls .append(line.split(","))
fo.close()
  • 将数据写入csv格式的文件
1
2
3
4
5
ls = [[], [], []]  # 二维列表
f = open(fname, 'w')
for item in ls:
f.write(','.join(item) + '\n')
fo.close()
  • 遍历二维数据
1
2
3
4
ls = [[1, 2], [3, 4], [5, 6]]  # 二维列表
for row in ls:
for column in row:
print(column)

35.绘制词云

  • 英文
1
2
3
4
import wordcloud
w = wordcloud.WordCloud()
w.generate("Python and WordCloud")
w.to_file("pic.png")
  • 中文
1
2
3
4
5
6
7
8
import jieba
import wordcloud
txt = "程序设计语言是计算机能够理解和识别用户\
操作意图的一种交互体系,它按照特定规则组织计算\
机指令,使计算机能够自动进行各种运算处理"
w = wordcloud.WordCloud(width=1000, font_path="msyh.ttc", height=700)
w.generate(" ".join(jieba.lcut(txt)))
w.to_file("pic.png")

效果:

词云


36.政府工作报告词云

1
2
3
4
5
6
7
8
9
10
11
import jieba
import wordcloud
f = open("fname.txt", "r", encoding="utf-8")
t = f.read()
f.close()
ls = jieba.lcut(t)
txt = " ".join(ls)
w = wordcloud.WordCloud(width=1000, height=700,
font_path="msyh.ttc", background_color="white")
w.generate(txt)
w.to_file("pic.png")

37.体育竞技分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from random import *


def printIntro():
print("这个程序模拟两个选手A和B的某种竞技比赛")
print("程序运行需要A和B的能力值(以0到1之间的小数表示)")


def getInputs():
a = eval(input("请输入选手A的能力值(0-1):"))
b = eval(input("请输入选手B的能力值(0-1):"))
n = eval(input("模拟比赛的场次:"))
return a, b, n


def printSunmary(winsA, winsB):
n = winsA + winsB
print("竞技分析开始, 共模拟{}场比赛".format(n))
print("选手A获胜{}场比赛, 占比{:0.1%}".format(winsA, winsA/n))
print("选手B获胜{}场比赛, 占比{:0.1%}".format(winsB, winsB/n))


def gameOver(a, b):
return a == 15 or b == 15


def simOneGame(probA, probB):
scoreA, scoreB = 0, 0
serving = "A"
while not gameOver(scoreA, scoreB):
if serving == "A":
if random() < probA:
scoreA += 1
else:
serving = "B"
else:
if random() < probB:
scoreB += 1
else:
serving = "A"
return scoreA, scoreB


def simNGames(n, probA, probB):
winsA, winsB = 0, 0
for i in range(n):
scoreA, scoreB = simOneGame(probA, probB)
if scoreA > scoreB:
winsA += 1
else:
winsB += 1
return winsA, winsB


def main():
printIntro()
probA, probB, n = getInputs()
winsA, winsB = simNGames(n, probA, probB)
printSunmary(winsA, winsB)


main()

38.第三方库自动安装脚本

1
2
3
4
5
6
7
8
import os
libs = {"numpy", "matplotlib", "pillow", "requests", "jieba", "pygame"}
try:
for lib in libs:
os.system("pip install " + lib)
print("Successful")
except:
print("Failed Somehow")

39.python-docx库进行文本处理

1
2
3
4
5
6
from docx import Document
document = Document()
document.add_heading('Document Title', 0)
p = document.add_paragraph('A plain paragraph having some ')
document.add_page_break()
document.save('demo.docx')

40.Requests 库的使用

  • Requests库的7个主要方法:
方法 说明
requests.request() 构造一个请求,支撑以下各方法的基础方法
requests.get() 获取 HTML 网页的主要方法,对应于 HTTP 的 GET
requests.head() 获取 HTML 网页头信息的方法,对应于 HTTP 的 HEAD
requests.post() 向 HTML 网页提交 POST 请求的方法,对应于 HTTP 的 POST
requests.put() 向 HTML 网页提交 PUT 请求的方法,对应于 HTTP 的 PUT
requests.patch() 向 HTML 网页提交局部修改请求,对应于 HTTP 的 PATCH
requests.delete() 向 HTML 页面提交删除请求,对应于 HTTP 的 DELETE
  • Reponse 对象的属性:
属性 说明
r.status_code HTTP 请求的返回状态,200表示连接成功,404表示失败
r.text HTTP 相应内容的字符串形式,即,url 对应的页面内容
r.encoding 从 HTTP header 中猜测的响应内容编码方式
r.apparent_encoding 从内容中分析出的响应内容编码方式(备选编码方式)
r.content HTTP 响应内容的二进制形式
  • 爬取百度网页内容:
1
2
3
4
5
6
7
8
import requests
r = requests.get("http://www.baidu.com")
print(r.status_code)
print(r.text)
print(r.encoding)
print(r.apparent_encoding)
r.encoding = 'utf-8'
print(r.text)
  • 理解 Request 库的异常:
异常 说明
requests.ConnectionError 网络连接错误异常,如 DNS 查询失败、拒绝连接等
requests.HTTPError HTTP 错误异常
requests.URLRequired URL 缺失异常
requests.TooManyRedirects 超过最大重定向次数,产生重定向异常
requests.ConnectTimeout 连接远程服务器超时异常
requests.Timeout 请求 URL 超时,产生超时异常
r.raise_for_status() 如果不是200,产生异常requests.HTTPError
  • 爬取网页的通用代码框架:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests


def getHTMLText(url):
try:
# r = requests.get(url, timeout=30)
kv = {'user-agent': 'Mozilla/5.0'} # 模拟浏览器访问
r = requests.get(url, headers=kv, timeout=30)
r.raise_for_status() # 如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"


if __name__ == "__main__":
url = "http://www.baidu.com"
print(getHTMLText(url))
  • requests的请求方式:
1
2
3
4
5
6
7
8
requests.request(method, url, **kwargs)
requests.request('GET', url, **kwargs)
requests.request('HEAD', url, **kwargs)
requests.request('POST', url, **kwargs)
requests.request('PUT', url, **kwargs)
requests.request('PATCH', url, **kwargs)
requests.request('delete', url, **kwargs)
requests.request('OPTIONS', url, **kwargs)
  • 访问京东:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests


def getHTMLText(url):
try:
kv = {'user-agent': 'Mozilla/5.0'} # 模拟浏览器访问
r = requests.get(url, headers=kv, timeout=30)
r.raise_for_status() # 如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"


if __name__ == "__main__":
url = 'https://item.jd.com/100028056854.html'
print(getHTMLText(url))
  • 百度搜索全代码:
1
2
3
4
5
6
7
8
9
10
import requests
keyword = 'Python'
try:
kv = {'wd': keyword}
r = requests.get("http://www.baidu.com/s", params=kv)
print(r.request.url)
r.raise_for_status()
print(r.text)
except:
print("爬取失败")
  • 爬取图片并保存:
1
2
3
4
5
6
7
8
9
10
import requests
image_url = 'http://img0.dili360.com/ga/M02/33/7C/wKgBzFSbqQyAJVAuAARB8cSWH_w695.tub.jpg@!rw14'
try:
response = requests.get(image_url)
print(response.content)

with open('pic.jpg', 'wb') as f:
f.write(response.content)
except:
print('爬取失败')

41.beautifulsoup4 库的使用

1
2
3
4
5
6
7
8
import requests
from bs4 import BeautifulSoup
r = requests.get("https://www.baidu.com/")
r.raise_for_status() # 如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
demo = r.text
soup = BeautifulSoup(demo, "html.parser")
print(soup.prettify())

42.创建 Cat 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Cat:
def __init__(self, name): # 这里设置类的属性
self.name = name
print('%s appeared.' % self.name)

def __del__(self):
print('%s disappeared.' % self.name)

def __str__(self):
return 'He is a cat named %s.' % self.name

def eat(self):
print("%s is eating." % self.name)

def drink(self):
print('%s is drinking.' % self.name)


def main():
tom = Cat('Tom')
print(tom)
tom.eat()
tom.drink()


main()

43.创建家具类 HouseItem 和房屋类 House

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class HouseItem:
def __init__(self, name, area):
self.name = name
self.area = area

def __str__(self):
return '[%s] 占地 %.2f' % (self.name, self.area)


class House:
def __init__(self, house_type, area):
self.house_type = house_type
self.area = area
self.free_area = area
self.item_list = []

def __str__(self):
return '户型: %s\n总面积: %.2f\n剩余:%.2f\n家具: %s' \
% (self.house_type, self.area, self.free_area, self.item_list)

def add_item(self, item):
print('要添加 %s' % item)
if item.area > self.free_area:
print('%s 的面积太大了,无法添加' % item.name)
return
self.item_list.append(item.name)
self.free_area -= item.area


def main():
bed = HouseItem('席梦思', 4)
chest = HouseItem('衣柜', 2)
table = HouseItem('餐桌', 1.5)

my_house = House('三室两厅', 100)
print(my_house)
my_house.add_item(bed)
my_house.add_item(chest)
my_house.add_item(table)
print(my_house)


main()

44.属性可以是另外一个类创建的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Gun:
def __init__(self, model):
self.model = model
self.bullet_count = 0

def add_bullet(self, count):
self.bullet_count += count

def shoot(self):
if self.bullet_count <= 0:
print('[%s] 没有子弹了...' % self.model)
return
self.bullet_count -= 1
print('[%s] 突突突... [剩余子弹 %d]' % (self.model, self.bullet_count))


class Soldier:
def __init__(self, name):
self.name = name
# 新兵没有枪
self.gun = None

'''
is 和 == 的区别:
is 用于判断 两个变量 引用对象是否为同一个
== 用于判断 引用变量的值 是否相等
'''

def fire(self):
if self.gun is None:
print('[%s] 还没有枪...' % self.name)
return
if self.gun.bullet_count <= 0:
self.gun.add_bullet(50)
print('%s 装弹完毕,即将开火!' % self.name)
self.gun.shoot()

def __str__(self):
return 'I am a soldier named %s.' % self.name


def main():
ak47 = Gun('AK47')
jack = Soldier('Jack')
print(jack)
jack.gun = ak47
jack.fire()
jack.fire()
jack.fire()


if __name__ == '__main__':
main()

45.私有属性和私有方法

在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Women:
def __init__(self, name):
self.name = name
self.__age = 18 # 私有属性

def secret(self):
print('%s 的年龄是 %d' % (self.name, self.__age))


def main():
mary = Women('Mary')
mary.secret()


if __name__ == '__main__':
main()

如果想在外部访问类的私有属性,在属性名前面加上 __类名 即可,Python并没有真正意义上的私有


46.继承

  • 示例1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Person(object):
def __init__(self, name):
self.name = name

def speak(self):
print('hello')

def move(self):
print('run')


class Student(Person):
def __init__(self, name, ID):
self.name = name
self.ID = ID

def speak(self):
super().speak() # 调用父类方法
print('I am a student.')

def task(self):
print('do homework')


def main():
jack = Student('Jack', '20144245')

jack.speak()
jack.move()
jack.task()


if __name__ == '__main__':
main()
  • 示例2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Person(object):
def __init__(self):
pass

def __del__(self):
pass

def speak(self):
print('hello')

def move(self):
print('run')


class Student(Person):
def __init__(self):
pass

def __del__(self):
pass

def speak(self):
super().speak() # 调用父类方法
print('I am a student.')

def task(self):
print('do homework')


def main():
jack = Student()

jack.speak()
jack.move()
jack.task()


if __name__ == '__main__':
main()
  • 示例3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Person(object):
def __init__(self):
self.__name = 'person'

def __siyou(self):
print('父类的私有方法')

def gongyou(self):
print('在父类中调用私有属性和方法')
print(self.__name)
self.__siyou()


class Student(Person):
def test(self):
print('在子类中调用父类的公有方法,进一步间接调用父类的私有方法')
super().gongyou()


def main():
jack = Student()
jack.test()


if __name__ == '__main__':
main()
  • 示例4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 多继承
class A(object):
def testA(self):
print('test A')


class B(object):
def testB(self):
print('test B')


class C(A, B):
pass


def main():
oc = C()
oc.testA()
oc.testB()


if __name__ == '__main__':
main()

如果父类之间存在同名的属性或方法,应该尽量避免使用多继承


47.多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Dog(object):
def __init__(self, name):
self.name = name

def game(self):
print('%s 蹦蹦跳跳地玩耍...' % self.name)


class XiaoTianDog(Dog):
def game(self):
print('%s 飞到天上去玩耍' % self.name)


class Person(object):
def __init__(self, name):
self.name = name

def game_with_dog(self, dog):
print('%s 和 %s 快乐地玩耍...' % (self.name, dog.name))
dog.game()


def main():
dog = Dog('旺财')
xiaotian = XiaoTianDog('旺财')

p = Person('小明')
p.game_with_dog(dog)
p.game_with_dog(xiaotian)


if __name__ == '__main__':
main()

48.类属性和类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Tool(object):
count = 0 # 类属性

def __init__(self, name):
self.name = name
Tool.count += 1


def main():
too11 = Tool('斧头')
too12 = Tool('锤子')
too13 = Tool('水桶')
print(Tool.count)


if __name__ == '__main__':
main()

49.类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Tool(object):
count = 0 # 类属性

# 类方法
@classmethod
def show_tool_count(cls):
print(Tool.count)

def __init__(self, name):
self.name = name
Tool.count += 1


def main():
too11 = Tool('斧头')
too12 = Tool('锤子')
too13 = Tool('水桶')
Tool.show_tool_count()


if __name__ == '__main__':
main()

50.静态方法

如果某个方法既不访问类属性,也不访问实例属性,可以将其设为静态方法

  • 示例1
1
2
3
4
5
6
7
8
9
10
11
12
class Dog(object):
@staticmethod # 静态方法
def run():
print('小狗要跑')


def main():
Dog.run()


if __name__ == '__main__':
main()
  • 示例2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Game(object):
top_score = 0

def __init__(self, player_name):
self.player_name = player_name

@staticmethod
def show_help():
print('帮助信息:让僵尸进入大门')

@classmethod
def show_top_score(cls):
print('历史记录: %d' % Game.top_score)

def start_game(self):
print('%s 开始游戏...' % self.player_name)


def main():
Game.show_help()
Game.show_top_score()
game = Game('小明')
game.start_game()


if __name__ == '__main__':
main()

51.重写 new 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MusicPlayer(object):
def __init__(self):
print('播放器初始化')

# 重写new方法
def __new__(cls, *args, **kwargs):
# 1.创建对象时,new方法会被自动调用
print('创建对象 分配空间')
# 2.为对象分配空间
instance = super().__new__(cls)
# 3.返回对象的引用
return instance


def main():
player = MusicPlayer()
print(player)


if __name__ == '__main__':
main()

52.单例设计模式 设计 一个单例类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class MusicPlayer(object):
# 记录第一个被创建对象的引用
instance = None

# 记录是否执行过初始化动作
init_flag = False

# 重写new方法
def __new__(cls, *args, **kwargs):
# 1.判断类属性是否是空对象
if cls.instance is None:
# 2.调用父类的方法为第一个对象分配空间
cls.instance = super().__new__(cls)
# 3.返回类属性保存的第一个对象的引用
return cls.instance

def __init__(self):
if MusicPlayer.init_flag:
return
print('初始化播放器')
MusicPlayer.init_flag = True


def main():
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)


if __name__ == '__main__':
main()