第三章 Python基础
数据分析与挖掘系列教程
目录
1. 数据结构与方法
1.1 变量赋值
两种赋值方式
python
# 方式1:直接赋值
name = "张三"
age = 25
# 方式2:交互式输入
user_input = input("请输入内容:")
# 注意:input()返回的永远是字符串类型⚠️ 重要提示:input() 函数返回的值始终是字符串,需要类型转换才能用于数值计算。
python
age = int(input("请输入年龄:")) # 转换为整数
price = float(input("请输入价格:")) # 转换为浮点数1.2 列表(List)
特性概览
- 构造符号:方括号
[] - 元素类型:无限制(数值、字符串、列表等)
- 有序性:支持索引和切片
- 可变性:可修改、增删元素
基础示例
python
# 创建列表
students = ['张三', '李四', '王五']
mixed_list = [1, 3.14, True, 'Python', [1, 2, 3]]索引技术
| 索引类型 | 语法 | 示例 | 说明 |
|---|---|---|---|
| 正向单索引 | list[n] | students[0] → '张三' | 从0开始计数 |
| 负向单索引 | list[-n] | students[-1] → '王五' | 从-1开始倒数 |
| 切片 | list[start:end:step] | students[0:2] → ['张三', '李四'] | 不包含end位置 |
| 无限切片 | list[:n] 或 list[n:] | students[:2] → 前2个元素 | 省略起点或终点 |
python
data = ['A', 'B', 'C', 'D', 'E', 'F']
# 正向索引
print(data[0]) # 'A' - 第1个元素
print(data[2]) # 'C' - 第3个元素
# 负向索引
print(data[-1]) # 'F' - 最后1个元素
print(data[-2]) # 'E' - 倒数第2个元素
# 切片操作
print(data[1:4]) # ['B', 'C', 'D'] - 索引1到3
print(data[::2]) # ['A', 'C', 'E'] - 每隔1个取值
print(data[::-1]) # ['F', 'E', 'D', 'C', 'B', 'A'] - 反转列表列表方法
增加元素
python
fruits = ['苹果', '香蕉']
# append: 添加单个元素到末尾
fruits.append('橙子') # ['苹果', '香蕉', '橙子']
# extend: 批量添加多个元素
fruits.extend(['葡萄', '西瓜']) # ['苹果', '香蕉', '橙子', '葡萄', '西瓜']
# insert: 在指定位置插入
fruits.insert(1, '草莓') # ['苹果', '草莓', '香蕉', '橙子', '葡萄', '西瓜']删除元素
python
numbers = [1, 2, 3, 4, 5, 3]
# pop: 根据索引删除(默认删除最后一个)
numbers.pop() # 删除5,返回5
numbers.pop(0) # 删除1,返回1
# remove: 根据值删除(仅删除第一个匹配项)
numbers.remove(3) # 删除第一个3
# clear: 清空列表
numbers.clear() # []修改元素
python
colors = ['红', '绿', '蓝']
colors[1] = '黄' # ['红', '黄', '蓝']其他常用方法
python
nums = [3, 1, 4, 1, 5, 9, 2, 6]
# 统计元素出现次数
print(nums.count(1)) # 2
# 查找元素索引
print(nums.index(5)) # 4
# 排序(会修改原列表)
nums.sort() # 升序排序
nums.sort(reverse=True) # 降序排序
# 反转列表
nums.reverse()
# 复制列表
nums_copy = nums.copy()1.3 元组(Tuple)
特性概览
- 构造符号:圆括号
() - 不可变性:创建后无法修改
- 性能优势:比列表更快,占用内存更少
- 适用场景:存储不应被修改的数据
python
# 创建元组
coordinates = (10, 20)
person = ('张三', 25, '北京')
# 单元素元组需要加逗号
single = (42,) # 正确
not_tuple = (42) # 这是整数,不是元组
# 元组支持索引和切片(与列表相同)
print(person[0]) # '张三'
print(person[-1]) # '北京'
# 仅有的两个方法
print(person.count('张三')) # 1
print(person.index(25)) # 1⚠️ 元组的不可变性:元组本身不可变,但如果元组包含可变对象(如列表),该对象的内容可以改变。
python
data = (1, 2, [3, 4])
# data[0] = 10 # 报错!元组不可修改
data[2].append(5) # 可以!修改列表内容
print(data) # (1, 2, [3, 4, 5])1.4 字典(Dictionary)
特性概览
- 构造符号:大括号
{} - 存储方式:键值对(key: value)
- 键的要求:唯一且不可变(字符串、数字、元组)
- 无序性:Python 3.7+ 保持插入顺序
python
# 创建字典
student = {
"姓名": "张三",
"年龄": 20,
"专业": "计算机科学",
"成绩": [85, 90, 88]
}
# 嵌套字典
company = {
"名称": "科技公司",
"员工": {
"技术部": ["张三", "李四"],
"市场部": ["王五", "赵六"]
}
}字典操作
获取值
python
# 方式1:键索引(键不存在会报错)
print(student["姓名"]) # '张三'
# 方式2:get方法(键不存在返回None或默认值)
print(student.get("姓名")) # '张三'
print(student.get("电话")) # None
print(student.get("电话", "未设置")) # '未设置'增加/修改
python
scores = {"数学": 90, "英语": 85}
# 直接赋值
scores["物理"] = 88 # 新增
scores["数学"] = 95 # 修改
# setdefault:仅当键不存在时添加
scores.setdefault("化学", 80) # 新增
scores.setdefault("数学", 100) # 不修改已有值
# update:批量更新
scores.update({"语文": 92, "数学": 96})删除
python
info = {"name": "Tom", "age": 25, "city": "Beijing"}
# pop:删除指定键
age = info.pop("age") # 返回25
# popitem:删除最后插入的键值对(3.7+)
item = info.popitem() # 返回 ('city', 'Beijing')
# del:删除指定键
del info["name"]
# clear:清空字典
info.clear()常用方法
python
book = {
"title": "Python编程",
"author": "张三",
"year": 2024
}
# 获取所有键
print(book.keys()) # dict_keys(['title', 'author', 'year'])
# 获取所有值
print(book.values()) # dict_values(['Python编程', '张三', 2024])
# 获取所有键值对
print(book.items()) # dict_items([('title', 'Python编程'), ...])
# 遍历字典
for key, value in book.items():
print(f"{key}: {value}")1.5 方法 vs 函数
| 特性 | 方法(Method) | 函数(Function) |
|---|---|---|
| 归属 | 属于特定对象/类 | 独立存在 |
| 调用 | 对象.方法() | 函数(参数) |
| 示例 | list.append() | len(), print() |
python
# 方法调用
my_list = [1, 2, 3]
my_list.append(4) # append是列表的方法
# 函数调用
length = len(my_list) # len是内置函数
print(length) # print是内置函数卫哥の上课笔记 / 内部资料
2. 流程控制语句
2.1 条件语句(if-elif-else)
基本语法
python
if 条件1:
代码块1
elif 条件2:
代码块2
else:
代码块3⚠️ 语法要点:
- 每个条件后必须有冒号
: - 代码块必须缩进(通常4个空格)
elif不是elseifelse后面不写条件
实例:成绩等级判定
python
score = int(input("请输入成绩:"))
if score >= 90:
grade = "优秀"
elif score >= 80:
grade = "良好"
elif score >= 60:
grade = "及格"
else:
grade = "不及格"
print(f"成绩等级:{grade}")条件表达式(三元运算符)
python
# 传统写法
if x > 0:
result = "正数"
else:
result = "非正数"
# 简洁写法
result = "正数" if x > 0 else "非正数"2.2 for循环
基本语法
python
for 变量 in 可迭代对象:
代码块常见用法
python
# 遍历列表
fruits = ['苹果', '香蕉', '橙子']
for fruit in fruits:
print(fruit)
# 遍历字符串
for char in "Python":
print(char)
# 使用range生成数字序列
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(1, 6): # 1, 2, 3, 4, 5
print(i)
for i in range(0, 10, 2): # 0, 2, 4, 6, 8
print(i)
# 遍历字典
person = {"name": "Tom", "age": 25}
for key in person:
print(key, person[key])
for key, value in person.items():
print(f"{key}: {value}")实例:计算1-100偶数和
python
total = 0
for num in range(1, 101):
if num % 2 == 0:
total += num
print(f"1-100偶数和:{total}") # 2550enumerate:同时获取索引和值
python
colors = ['红', '绿', '蓝']
for index, color in enumerate(colors):
print(f"索引{index}: {color}")卫哥の上课笔记 / 内部资料
2.3 列表推导式
基本语法
python
[表达式 for 变量 in 可迭代对象 if 条件]对比传统循环
python
# 传统for循环
squares = []
for x in range(10):
squares.append(x ** 2)
# 列表推导式(更简洁)
squares = [x ** 2 for x in range(10)]高级用法
python
# 带条件筛选
even_squares = [x ** 2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]
# 嵌套推导式
matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
# 字符串处理
words = ['hello', 'WORLD', 'Python']
upper_words = [w.upper() for w in words]
# ['HELLO', 'WORLD', 'PYTHON']2.4 while循环
基本语法
python
while 条件:
代码块for vs while
| 特性 | for循环 | while循环 |
|---|---|---|
| 适用场景 | 已知迭代次数/对象 | 未知迭代次数 |
| 示例 | 遍历列表 | 用户登录验证 |
实例:登录验证
python
max_attempts = 3
attempts = 0
while attempts < max_attempts:
username = input("用户名:")
password = input("密码:")
if username == "admin" and password == "123456":
print("登录成功!")
break
else:
attempts += 1
remaining = max_attempts - attempts
if remaining > 0:
print(f"登录失败,还有{remaining}次机会")
else:
print("账户已锁定,请联系管理员")无限循环与break
python
# 无限循环(需要break退出)
while True:
command = input("输入命令(输入'退出'结束):")
if command == "退出":
break
print(f"执行命令:{command}")3. 字符串处理
3.1 字符串基础
创建方式
python
# 单引号
s1 = 'Hello'
# 双引号
s2 = "World"
# 三引号(支持多行)
s3 = '''这是
多行
字符串'''
# 原始字符串(忽略转义符)
path = r"C:\Users\name\Documents"字符串是不可变的
python
text = "Python"
# text[0] = 'J' # 报错!字符串不可修改
# 正确做法:创建新字符串
text = "J" + text[1:] # "Jython"3.2 字符串方法
切片操作
python
text = "Python Programming"
print(text[0:6]) # "Python"
print(text[7:]) # "Programming"
print(text[:6]) # "Python"
print(text[::2]) # "Pto rgamn"
print(text[::-1]) # "gnimmargorP nohtyP" (反转)常用方法速查
| 方法 | 功能 | 示例 |
|---|---|---|
split(sep) | 分割字符串 | "a-b-c".split("-") → ['a', 'b', 'c'] |
join(iterable) | 连接字符串 | "-".join(['a', 'b']) → "a-b" |
strip() | 去除首尾空白 | " hello ".strip() → "hello" |
replace(old, new) | 替换子串 | "hello".replace("l", "L") → "heLLo" |
upper() / lower() | 大小写转换 | "Hello".upper() → "HELLO" |
startswith(prefix) | 检查开头 | "Python".startswith("Py") → True |
endswith(suffix) | 检查结尾 | "test.py".endswith(".py") → True |
find(sub) | 查找子串 | "hello".find("ll") → 2 |
count(sub) | 计数子串 | "banana".count("a") → 3 |
实用示例
python
# 提取身份证号中的出生日期
print("123456198901017890"[6:14]) # 输出:19890101
# 将手机号中间四位替换为*
tel = "13612345678"
print(tel.replace(tel[3:7], "****")) # 输出:136****5678
# 分割字符串
print("12345@qq.com".split("@")) # 输出:["12345", "qq.com"]
# 用逗号连接字符串
print(",".join("Python")) # 输出:P,y,t,h,o,n
# 去除空白
print(" 今天星期日 ".lstrip()) # 去除左空白
print(" 今天星期日 ".rstrip()) # 去除右空白
print(" 今天星期日 ".strip()) # 去除首尾空白
# 子串计数
string5 = "中国方案引领世界前行,展现了中国应势而为、勇于担当的大国风范!"
print(string5.count("中国")) # 输出:2
# 查找子串位置
string6 = "我是一名Python用户,Python给我的工作带来了很多便捷。"
print(string6.index("Python")) # 输出:6
print(string6.find("Python")) # 输出:6
# 判断字符串开头和结尾
string7 = "2017年已过,但全新的2018年即将到来"
print(string7.startswith("2018年")) # 输出:False
print(string7.endswith("2018年")) # 输出:False卫哥の上课笔记 / 内部资料
3.3 正则表达式
导入re模块
python
import re核心函数
| 函数 | 功能 | 语法 |
|---|---|---|
findall() | 查找所有匹配项 | re.findall(pattern, string) |
search() | 查找第一个匹配项 | re.search(pattern, string) |
sub() | 替换匹配项 | re.sub(pattern, repl, string) |
split() | 按模式分割 | re.split(pattern, string) |
常用正则符号
| 符号 | 含义 | 示例 |
|---|---|---|
. | 任意字符(除换行符) | a.c 匹配 "abc", "a1c" |
\d | 数字 [0-9] | \d{3} 匹配 "123" |
\D | 非数字 | \D+ 匹配 "abc" |
\w | 字母、数字、下划线 | \w+ 匹配 "hello_123" |
\s | 空白字符 | \s+ 匹配空格、制表符 |
* | 0次或多次 | ab* 匹配 "a", "ab", "abb" |
+ | 1次或多次 | ab+ 匹配 "ab", "abb" |
? | 0次或1次 | ab? 匹配 "a", "ab" |
{m,n} | m到n次 | a{2,4} 匹配 "aa", "aaa", "aaaa" |
[] | 字符集 | [abc] 匹配 "a", "b", "c" |
[^] | 非字符集 | [^0-9] 匹配非数字 |
| | 或 | cat|dog 匹配 "cat" 或 "dog" |
() | 分组/捕获 | (ab)+ 匹配 "ab", "abab" |
实战案例
提取邮箱地址
python
text = "联系我:admin@example.com 或 support@test.org"
emails = re.findall(r'\w+@\w+\.\w+', text)
print(emails) # ['admin@example.com', 'support@test.org']提取手机号
python
text = "我的手机号是13812345678,备用号码是15987654321"
phones = re.findall(r'1[3-9]\d{9}', text)
print(phones) # ['13812345678', '15987654321']清理HTML标签
python
html = "<p>这是<b>加粗</b>文本</p>"
clean_text = re.sub(r'<[^>]+>', '', html)
print(clean_text) # "这是加粗文本"提取日期
python
text = "会议时间:2024-03-15 和 2024/04/20"
dates = re.findall(r'\d{4}[-/]\d{2}[-/]\d{2}', text)
print(dates) # ['2024-03-15', '2024/04/20']分组捕获
python
text = "价格:¥199.99元"
match = re.search(r'¥(\d+\.\d{2})', text)
if match:
price = match.group(1) # "199.99"
print(f"提取的价格:{price}")卫哥の上课笔记 / 内部资料
4. 函数定义与使用
4.1 匿名函数(Lambda)
语法格式
python
lambda 参数: 表达式特点
- 单行表达式
- 无需def关键字
- 常用于临时性、简单的函数
基础示例
python
# 普通函数
def add(x, y):
return x + y
# 等价的Lambda函数
add_lambda = lambda x, y: x + y
print(add(3, 5)) # 8
print(add_lambda(3, 5)) # 8实用场景
排序
python
# 按字符串长度排序
words = ['python', 'java', 'c', 'javascript']
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words) # ['c', 'java', 'python', 'javascript']
# 按字典值排序
scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78}
sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
print(sorted_scores) # [('Bob', 92), ('Alice', 85), ('Charlie', 78)]数据处理
python
# map:对每个元素应用函数
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # [1, 4, 9, 16, 25]
# filter:筛选元素
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # [2, 4]4.2 自定义函数(def)
基本语法
python
def 函数名(参数列表):
"""文档字符串(可选)"""
函数体
return 返回值 # 可选参数类型
必需参数
python
def greet(name):
return f"你好,{name}!"
print(greet("张三")) # "你好,张三!"
# greet() # 报错:缺少必需参数默认参数
python
def power(base, exponent=2):
return base ** exponent
print(power(3)) # 9 (3^2)
print(power(3, 3)) # 27 (3^3)关键字参数
python
def create_profile(name, age, city="未知"):
return f"{name}, {age}岁, 来自{city}"
# 位置传参
print(create_profile("张三", 25, "北京"))
# 关键字传参(顺序可变)
print(create_profile(age=25, name="张三", city="上海"))可变参数
python
# *args:接收任意数量位置参数(元组)
def sum_all(*numbers):
return sum(numbers)
print(sum_all(1, 2, 3, 4)) # 10
# **kwargs:接收任意数量关键字参数(字典)
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Tom", age=25, city="Beijing")返回值
python
# 单个返回值
def square(x):
return x ** 2
# 多个返回值(返回元组)
def divide(a, b):
quotient = a // b
remainder = a % b
return quotient, remainder
q, r = divide(10, 3)
print(q, r) # 3 1
# 无返回值(返回None)
def print_message(msg):
print(msg)文档字符串
python
def calculate_bmi(weight, height):
"""
计算BMI指数
参数:
weight (float): 体重(千克)
height (float): 身高(米)
返回:
float: BMI值
"""
return weight / (height ** 2)
# 查看文档
help(calculate_bmi)
print(calculate_bmi.__doc__)4.3 实用函数示例
示例1:温度转换
python
def celsius_to_fahrenheit(celsius):
"""摄氏度转华氏度"""
return celsius * 9/5 + 32
def fahrenheit_to_celsius(fahrenheit):
"""华氏度转摄氏度"""
return (fahrenheit - 32) * 5/9
print(f"25°C = {celsius_to_fahrenheit(25)}°F")
print(f"77°F = {fahrenheit_to_celsius(77):.1f}°C")示例2:列表去重保序
python
def unique_list(items):
"""去除列表重复元素,保持顺序"""
seen = set()
result = []
for item in items:
if item not in seen:
seen.add(item)
result.append(item)
return result
numbers = [1, 3, 2, 3, 4, 1, 5]
print(unique_list(numbers)) # [1, 3, 2, 4, 5]示例3:递归函数
python
def factorial(n):
"""计算阶乘(递归)"""
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
def fibonacci(n):
"""斐波那契数列(递归)"""
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print([fibonacci(i) for i in range(10)])
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]卫哥の上课笔记 / 内部资料
5. 实战案例:网页爬虫
5.1 案例:爬取天气数据
技术栈
- requests:发送HTTP请求
- re:正则表达式提取数据
- pandas:数据处理与存储
- time & random:请求延迟(防反爬)
完整代码
python
import requests
import time
import random
import pandas as pd
import re
# 1. 配置请求头(模拟浏览器)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': '*/*',
'Connection': 'keep-alive'
}
# 2. 生成目标URL列表
urls = []
for year in range(2020, 2024):
for month in range(1, 13):
url = f'http://tianqi.2345.com/t/wea_history/5/{year}/{month:02d}/58362.htm'
urls.append(url)
# 3. 爬取数据
all_data = []
for idx, url in enumerate(urls, 1):
try:
# 随机延迟3-6秒(避免被封)
time.sleep(random.uniform(3, 6))
# 发送请求
response = requests.get(url, headers=headers, timeout=10)
response.encoding = 'utf-8'
# 正则提取数据
dates = re.findall(r'"ymd":"(.*?)"', response.text)
high_temp = re.findall(r'"bendu":"(.*?)℃"', response.text)
low_temp = re.findall(r'"wendu":"(.*?)℃"', response.text)
weather = re.findall(r'"tianqi":"(.*?)"', response.text)
# 组织数据
df = pd.DataFrame({
'日期': dates,
'最高温': high_temp,
'最低温': low_temp,
'天气': weather
})
all_data.append(df)
print(f"已完成 {idx}/{len(urls)}")
except Exception as e:
print(f"URL {url} 爬取失败:{e}")
# 4. 合并并保存数据
if all_data:
final_data = pd.concat(all_data, ignore_index=True)
final_data.to_csv('weather_data.csv', index=False, encoding='utf-8-sig')
print(f"\n爬取完成!共 {len(final_data)} 条数据")5.2 爬虫关键技术
反爬策略应对
| 反爬手段 | 应对方法 |
|---|---|
| User-Agent检测 | 设置headers模拟浏览器 |
| 访问频率限制 | 随机延迟(time.sleep) |
| IP封禁 | 使用代理IP池 |
| JavaScript渲染 | 使用Selenium/Playwright |
请求头设置
python
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Referer': 'https://www.example.com', # 来源页面
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cookie': 'session_id=xxx' # 登录态
}异常处理
python
try:
response = requests.get(url, timeout=10)
response.raise_for_status() # 检查HTTP错误
except requests.Timeout:
print("请求超时")
except requests.HTTPError as e:
print(f"HTTP错误:{e}")
except Exception as e:
print(f"未知错误:{e}")5.3 数据清洗示例
python
import pandas as pd
# 读取爬取的数据
df = pd.read_csv('weather_data.csv')
# 数据清洗
df['日期'] = pd.to_datetime(df['日期']) # 转换日期格式
df['最高温'] = df['最高温'].str.replace('℃', '').astype(int)
df['最低温'] = df['最低温'].str.replace('℃', '').astype(int)
# 数据分析
print(df.describe()) # 统计描述
print(df['天气'].value_counts()) # 天气分布
# 可视化(需要matplotlib)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文显示
df.plot(x='日期', y=['最高温', '最低温'], figsize=(12, 6))
plt.title('气温变化趋势')
plt.xlabel('日期')
plt.ylabel('温度(℃)')
plt.show()附录:学习资源
官方文档
- Python官方文档:https://docs.python.org/zh-cn/3/
- Pandas文档:https://pandas.pydata.org/docs/
- Requests文档:https://docs.python-requests.org/
推荐练习平台
- LeetCode(算法):https://leetcode.cn/
- Kaggle(数据分析):https://www.kaggle.com/
- HackerRank:https://www.hackerrank.com/
进阶学习路径
- 基础巩固:数据结构 → 流程控制 → 函数
- 数据处理:Pandas → NumPy → 数据可视化
- 爬虫进阶:Selenium → Scrapy框架
- 数据分析:统计分析 → 机器学习 → 深度学习
快速参考
Python内置函数
python
# 类型转换
int(), float(), str(), list(), dict(), tuple()
# 数学运算
abs(), round(), max(), min(), sum(), pow()
# 序列操作
len(), sorted(), reversed(), enumerate(), zip()
# 输入输出
print(), input()
# 其他
type(), isinstance(), help(), dir()常用快捷操作
python
# 交换变量
a, b = b, a
# 多重赋值
x = y = z = 0
# 链式比较
1 < x < 10
# 条件表达式
result = "偶数" if num % 2 == 0 else "奇数"
# 列表去重
unique = list(set(my_list))
# 字典合并(Python 3.9+)
merged = dict1 | dict2编写日期:2024年
适用版本:Python 3.6+
文档状态:持续更新
© 2026 卫の课程教学资料
仅限学员学习使用,禁止任何形式传播
仅限学员学习使用,禁止任何形式传播
📢 版权声明:本文首发于 [https://zhangwei.gitbook.io/],禁止非法爬取或转载。 验证指纹 ID:GB-2026-0116