Python学习(第一部分 语法与数据结构/核心基础)

本文系统梳理 Python 基础语法的核心知识点,涵盖变量类型、控制流、数据结构、函数、模块、面向对象编程等内容,适合初学者系统学习或开发者查漏补缺。


一、基本语法

1.1 变量与数据类型

Python 是动态类型语言,变量无需声明类型,解释器自动推断。

基本数据类型:

  • int --- 整数,无大小限制(Python 3)

  • float --- 浮点数,双精度(64位),遵循 IEEE 754

  • complex --- 复数,如 3+4j,可用 .real / .imag 访问实部虚部

  • str --- 字符串,不可变序列

  • bool --- 布尔值,True/False(首字母大写),是 int 的子类(True==1, False==0

  • NoneType --- 空值,None 是唯一实例,表示"无"或"空"

类型转换与检查:

python 复制代码
# 类型转换
int("123")      # 123
float("3.14")   # 3.14
str(100)        # "100"
bool(1)         # True
bool(0)         # False
bool("")        # False

# 类型检查
type(123)                    # <class 'int'>
isinstance(123, int)         # True
isinstance(True, int)        # True(bool 是 int 的子类)

1.2 运算符

运算符分类表:

类别 运算符 说明
算术 + - * / // % ** 加、减、乘、除、整除、取模、幂
比较 == != > < >= <= 比较值是否相等、大小
逻辑 and or not 逻辑与、或、非(短路求值)
赋值 = += -= *= /= //= %= **= 赋值及复合赋值
成员 in / not in 检查元素是否在容器中
身份 is / is not 比较两个对象的内存地址是否相同

短路特性示例:

python 复制代码
# and 短路:左侧为假时,右侧不执行
False and print("不会执行")     # 什么都不打印

# or 短路:左侧为真时,右侧不执行
True or print("不会执行")       # 什么都不打印

# 利用短路实现默认值
name = user_input or "匿名用户"  # 如果 user_input 为空,使用默认值

==is 的区别:

python 复制代码
a = [1, 2, 3]
b = [1, 2, 3]

print(a == b)    # True  --- 值相等
print(a is b)    # False --- 不是同一个对象(内存地址不同)
print(a is a)    # True  --- 同一个对象

# 实用场景:判断是否为 None
x = None
if x is None:          # 推荐用 is,而非 ==
    print("x 是 None")

小整数驻留(Interning)注意:

python 复制代码
a = 256
b = 256
print(a is b)    # True(CPython 缓存了 -5 到 256 的小整数)

a = 257
b = 257
print(a is b)    # 可能是 False(不要在值比较时依赖 is)

1.3 运算符优先级(从高到低)

python 复制代码
() → ** → +x, -x, ~x → *, /, //, % → +, - → 
<<, >> → & → ^ → | → 比较运算 → not → and → or

口诀: 括号最高,幂次之,乘除模整除,加减,位移,位与,位异或,位或,比较,逻辑非,逻辑与,逻辑或,赋值最低。

python 复制代码
# 实际开发中,加括号让意图更清晰,不必死记优先级
result = (a + b) * (c - d) / (e ** 2)

1.4 控制流

条件判断:if / elif / else
python 复制代码
score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"

print(f"等级:{grade}")  # 等级:B

注意: Python 用缩进(推荐4个空格)表示代码块,不使用大括号。

for 循环
python 复制代码
# 基本用法
for i in range(5):
    print(i)                    # 0, 1, 2, 3, 4

# range 的三种形式
range(5)        # 0, 1, 2, 3, 4
range(2, 5)     # 2, 3, 4
range(0, 10, 2) # 0, 2, 4, 6, 8
range(10, 0, -1) # 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

# 遍历列表
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
    print(fruit)

# 遍历字典
person = {"name": "Alice", "age": 25, "city": "北京"}
for key in person:                      # 遍历键
    print(key)
for value in person.values():           # 遍历值
    print(value)
for key, value in person.items():       # 遍历键值对(最常用)
    print(f"{key}: {value}")

可迭代对象: 字符串、列表、元组、字典、集合、range()、文件对象等都可以被 for 遍历。

while 循环
python 复制代码
count = 0
while count < 5:
    print(f"计数:{count}")
    count += 1

# 适合循环次数不确定的场景
while True:
    user_input = input("输入 q 退出:")
    if user_input == 'q':
        break
break / continue / pass
python 复制代码
# break:立即终止整个循环
for i in range(10):
    if i == 5:
        break
    print(i)        # 输出 0, 1, 2, 3, 4

# continue:跳过本轮剩余代码,进入下一轮
for i in range(10):
    if i % 2 == 0:
        continue
    print(i)        # 只输出奇数 1, 3, 5, 7, 9

# pass:占位符,什么都不做
def my_function():   # 还没想好怎么实现
    pass

class MyClass:       # 先占个位
    pass

if condition:        # 条件分支暂时不处理
    pass
for...else 和 while...else
python 复制代码
# 循环正常结束(未被 break 打断)时执行 else 块
for item in [1, 2, 3]:
    if item == 10:
        print("找到了")
        break
else:
    print("循环正常结束,没有找到 10")

# 实际应用:查找质数
def is_prime(n):
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            print(f"{n} 不是质数,能被 {i} 整除")
            break
    else:
        print(f"{n} 是质数")

is_prime(17)  # 17 是质数
is_prime(24)  # 24 不是质数,能被 2 整除

1.5 输入与输出

print() 函数:

python 复制代码
name = "Alice"
age = 25

# f-string(Python 3.6+,推荐)
print(f"我叫{name},明年{age + 1}岁")

# format() 方法
print("我叫{},明年{}岁".format(name, age + 1))
print("{0} 今年 {1} 岁".format(name, age))      # 按位置序号

# 自定义分隔符和结尾
print("A", "B", "C", sep=", ")    # A, B, C
print("Hello", end=" ")           # 不换行
print("World")                    # Hello World

# 格式化数字
pi = 3.1415926
print(f"圆周率:{pi:.2f}")         # 圆周率:3.14
print(f"{12345678:,}")             # 12,345,678(千分位)
print(f"{42:b}")                   # 101010(二进制)

input() 函数:

python 复制代码
# input() 返回值始终是字符串类型
name = input("请输入你的名字:")
age = int(input("请输入你的年龄:"))    # 需要数字时手动转换
height = float(input("请输入身高(米):"))

print(f"{name},{age}岁,身高{height}米")

二、核心内置数据结构

2.1 列表 list --- 可变有序序列

创建列表
python 复制代码
# 多种创建方式
empty = []                          # 空列表
nums = [1, 2, 3, 4, 5]             # 直接赋值
chars = list("hello")              # ['h', 'e', 'l', 'l', 'o']
from_range = list(range(5))        # [0, 1, 2, 3, 4]
squares = [x**2 for x in range(5)] # 列表推导式 → [0, 1, 4, 9, 16]
访问与切片
python 复制代码
nums = [10, 20, 30, 40, 50]

# 索引
print(nums[0])     # 10
print(nums[-1])    # 50(负索引从尾部开始)
print(nums[-2])    # 40

# 切片 list[start:stop:step]
print(nums[1:4])   # [20, 30, 40](索引 1, 2, 3)
print(nums[:3])    # [10, 20, 30](从开头到索引 2)
print(nums[2:])    # [30, 40, 50](从索引 2 到末尾)
print(nums[::-1])  # [50, 40, 30, 20, 10](反转列表)
print(nums[::2])   # [10, 30, 50](步长为 2)

# 切片返回新列表(浅拷贝),不修改原列表
copied = nums[:]
print(copied is nums)  # False --- 不同对象
常用方法
python 复制代码
fruits = ["苹果", "香蕉"]

# 添加元素
fruits.append("橙子")                # 末尾追加 → ["苹果", "香蕉", "橙子"]
fruits.extend(["葡萄", "西瓜"])      # 扩展多个 → ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
fruits.insert(1, "梨")               # 在索引1处插入 → ["苹果", "梨", "香蕉", ...]

# 删除元素
fruits.remove("梨")                  # 删除第一个匹配值,不存在则 ValueError
last = fruits.pop()                   # 删除并返回末尾元素
second = fruits.pop(1)                # 删除并返回索引1的元素
del fruits[0]                         # 按索引删除
fruits.clear()                        # 清空列表

# 查找与统计
nums = [1, 2, 3, 2, 4, 2]
print(nums.index(2))      # 1 --- 第一个 2 的索引
print(nums.index(2, 2))   # 3 --- 从索引2开始查找
print(nums.count(2))      # 3 --- 2 出现了 3 次

# 排序(原地修改)
nums.sort()                          # 升序
nums.sort(reverse=True)              # 降序
words.sort(key=len)                  # 按长度排序
pairs.sort(key=lambda x: x[1])      # 按元组第二个元素排序

# 反转与拷贝
nums.reverse()                       # 原地反转
copy_nums = nums.copy()              # 浅拷贝,等价于 nums[:]
列表的 +*(注意陷阱)
python 复制代码
# 拼接与重复
print([1, 2] + [3, 4])   # [1, 2, 3, 4]
print([0] * 5)            # [0, 0, 0, 0, 0]

# ⚠️ 陷阱:[[]] * 3 是同一空列表的三份引用!
lists = [[]] * 3
lists[0].append(1)
print(lists)              # [[1], [1], [1]] --- 三个元素指向同一个列表!

# ✅ 正确做法:用列表推导式创建独立嵌套列表
lists = [[] for _ in range(3)]
lists[0].append(1)
print(lists)              # [[1], [], []] --- 三个独立的空列表

# 二维列表正确创建方式
matrix = [[0 for _ in range(4)] for _ in range(3)]
列表推导式(重要)
python 复制代码
# 基本形式:[表达式 for 变量 in 可迭代对象]
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 带条件过滤
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# if-else 形式(注意顺序!)
labels = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
# ['偶数', '奇数', '偶数', '奇数', '偶数']

# 嵌套循环(笛卡尔积)
pairs = [(x, y) for x in [1, 2] for y in ['a', 'b']]
# [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

# 同时遍历多个序列
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
passed = [f"{n}: {s}" for n, s in zip(names, scores) if s >= 80]
# ['Alice: 85', 'Bob: 92']

2.2 元组 tuple --- 不可变有序序列

创建元组
python 复制代码
# 创建方式
empty = ()                      # 空元组
point = (1, 2, 3)               # 多元素
single = (1,)                   # ⚠️ 单元素元组,逗号是关键!
not_tuple = (1)                 # 这只是带括号的整数,不是元组!
from_list = tuple([1, 2, 3])   # 从其他可迭代对象转换

print(type(single))      # <class 'tuple'>
print(type(not_tuple))    # <class 'int'>  ← 注意!不是元组
特性与元组解包
python 复制代码
# 不可变性
t = (1, 2, 3)
# t[0] = 10  # ❌ TypeError: 'tuple' object does not support item assignment

# 但如果元组包含可变对象,该可变对象内容可修改
t2 = (1, [2, 3], 4)
t2[1].append(5)
print(t2)  # (1, [2, 3, 5], 4) --- 列表本身被修改了

# 元组解包(Tuple Unpacking)
a, b = (1, 2)                # a=1, b=2
a, b, *rest = (1, 2, 3, 4, 5)  # a=1, b=2, rest=[3,4,5]
first, *_, last = (1, 2, 3, 4, 5) # first=1, last=5, 忽略中间部分

# 实用:一行交换两个变量的值
a, b = b, a                  # 本质是元组解包

# 函数返回多个值(实际返回元组)
def min_max(nums):
    return min(nums), max(nums)

low, high = min_max([3, 1, 4, 1, 5, 9])
print(low, high)  # 1 9

2.3 字符串 str --- 不可变序列(Unicode)

创建与格式化
python 复制代码
# 创建
s1 = '单引号'
s2 = "双引号"
s3 = '''多行
字符串'''                       # 三引号保留换行
s4 = str(100)                  # "100"

# ⭐ 字符串格式化(推荐优先级:f-string > format() > %)

# ① f-string(Python 3.6+,性能最优,最可读)
name = "Alice"
age = 30
print(f"我的名字是{name},明年{age + 1}岁")

# 格式化细节
pi = 3.1415926
print(f"圆周率:{pi:.2f}")      # 圆周率:3.14
print(f"{12345678:,}")          # 12,345,678(千分位)
print(f"{42:b}")                # 101010(二进制)
print(f"{'Hello':>10}")         # '     Hello'(右对齐宽度10)
print(f"{'Hello':0>10}")        # '00000Hello'(左补零)

# ② str.format() 方法
print("{} {}".format("Hello", "World"))
print("{1} {0}".format("World", "Hello"))    # 按位置序号
print("{name} {age}".format(name="Alice", age=25))  # 按关键字

# ③ % 格式化(旧式,不推荐新代码使用)
print("%s %d %f" % ("字符串", 123, 3.14))
常用方法
python 复制代码
s = "  Hello World  "

# 大小写转换
print(s.upper())          # "  HELLO WORLD  "
print(s.lower())          # "  hello world  "
print(s.title())          # "  Hello World  "
print(s.capitalize())     # "  hello world  "(仅首字符大写)

# 判断类型(返回 bool)
print("abc".isalpha())    # True --- 全字母
print("123".isdigit())    # True --- 全数字
print("abc123".isalnum())  # True --- 字母或数字
print("   ".isspace())    # True --- 全空白

# 查找与替换
print(s.find("World"))    # 8 --- 首次出现索引,未找到返回 -1
print(s.index("World"))   # 8 --- 类似 find,但未找到引发 ValueError
print(s.count("l"))       # 3 --- 统计出现次数
print(s.replace("World", "Python"))  # "  Hello Python  "

# 分割与连接
print(s.split())          # ['Hello', 'World'] --- 默认按空白分割
print("a,b,c".split(",")) # ['a', 'b', 'c']
print("-".join(["a", "b", "c"]))  # "a-b-c" --- ⭐ 高频使用!

# 修剪空白
print(s.strip())          # "Hello World" --- 移除两端空白
print(s.lstrip())         # "Hello World  " --- 移除左侧
print(s.rstrip())         # "  Hello World" --- 移除右侧

# 检查首尾
print("file.txt".endswith(".txt"))   # True
print("http://example.com".startswith("http"))  # True
编码与解码
python 复制代码
# 字符串 → 字节
text = "你好"
bytes_data = text.encode("utf-8")
print(bytes_data)        # b'\xe4\xbd\xa0\xe5\xa5\xbd'

# 字节 → 字符串
decoded_text = bytes_data.decode("utf-8")
print(decoded_text)      # 你好

2.4 字典 dict --- 可变映射(Python 3.7+ 保序)

创建字典
python 复制代码
# 多种创建方式
d1 = {}                                   # 空字典
d2 = {"name": "Alice", "age": 25}         # 直接赋值
d3 = dict(name="Alice", age=25)           # 关键字参数
d4 = dict([("name", "Alice"), ("age", 25)]) # 键值对序列
d5 = dict.fromkeys(["a", "b", "c"], 0)    # 批量创建相同值 → {'a': 0, 'b': 0, 'c': 0}

# ⚠️ 字典的键必须是不可变类型(可哈希)
valid_keys = {
    "str": 1,       # ✅ 字符串
    123: 2,         # ✅ 整数
    3.14: 3,        # ✅ 浮点数
    (1, 2): 4,      # ✅ 元组(元素也需全不可变)
}
# {[1, 2]: "bad"}  # ❌ 列表不可作为键(可变,不可哈希)
基本操作
python 复制代码
user = {"name": "Alice", "age": 25, "city": "北京"}

# ⭐ 取值(推荐用 get 方法避免 KeyError)
print(user["name"])           # Alice
# print(user["email"])        # ❌ KeyError: 'email'
print(user.get("email"))      # None(键不存在不报错)
print(user.get("email", "未知"))  # "未知"(提供默认值)

# 赋值与更新
user["age"] = 26              # 修改已有键
user["email"] = "alice@example.com"  # 新增键值对
user.update({"phone": "123456", "city": "上海"})  # 批量更新

# setdefault:键存在返回对应值,不存在则设置默认值并返回
# 不存在的键 → 设置并返回默认值
# 已存在的键 → 返回原值,不修改

# 删除
del user["phone"]             # 删除键,不存在则 KeyError
age = user.pop("age")         # 删除并返回值,可提供默认值
last = user.popitem()         # 删除并返回最后一个键值对(LIFO,3.7+)
user.clear()                  # 清空

# 成员检查(O(1) 平均复杂度)
if "name" in user:
    print("存在 name 键")

# 遍历
for key in user:                     # 遍历键
    print(key)
for value in user.values():          # 遍历值
    print(value)
for key, value in user.items():      # ⭐ 遍历键值对(最常用)
    print(f"{key}: {value}")
字典推导式
python 复制代码
# 基本形式
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 带条件
evens = {x: x**2 for x in range(10) if x % 2 == 0}
# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

# 反转键值对
original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}

2.5 集合 set / frozenset --- 无序不重复元素集

创建与特点
python 复制代码
# ⚠️ 空集合必须用 set(),{} 创建的是空字典!
empty_set = set()
empty_dict = {}
print(type(empty_set))  # <class 'set'>
print(type(empty_dict))  # <class 'dict'>

# 创建非空集合
s = {1, 2, 3}
s2 = set([1, 2, 2, 3, 3])    # {1, 2, 3} --- 自动去重
s3 = set("hello")             # {'h', 'e', 'l', 'o'} --- 注意顺序不固定且 l 只有一个

# 不可变集合
fs = frozenset([1, 2, 3])     # 不可修改,可哈希,可作为字典键

# 集合的元素必须是不可变类型
# {[1, 2]}  # ❌ TypeError: unhashable type: 'list'
基本操作
python 复制代码
s = {1, 2, 3}

# 添加与删除
s.add(4)            # 添加元素
s.remove(4)         # 删除元素,不存在则 KeyError
s.discard(4)        # 删除元素,不存在也不报错(推荐)
popped = s.pop()    # 随机删除并返回一个元素
s.clear()           # 清空

# 成员检查(O(1) 平均复杂度)
print(2 in {1, 2, 3})   # True

# 集合推导式
evens_squared = {x**2 for x in range(10) if x % 2 == 0}
# {0, 64, 4, 36, 16} --- 注意集合是无序的
数学集合运算(集合的精华)
python 复制代码
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

# 运算符方式(更直观)
print(a | b)    # {1, 2, 3, 4, 5, 6} --- 并集
print(a & b)    # {3, 4} --- 交集
print(a - b)    # {1, 2} --- 差集
print(a ^ b)    # {1, 2, 5, 6} --- 对称差集(在一边但不同时在两边)

# 方法方式(语义更明确)
print(a.union(b))                   # 并集
print(a.intersection(b))            # 交集
print(a.difference(b))              # 差集
print(a.symmetric_difference(b))    # 对称差集

# 关系判断
print({1, 2} <= {1, 2, 3})    # True --- 子集
print({1, 2, 3} >= {1, 2})     # True --- 超集
print({1, 2}.isdisjoint({3, 4}))  # True --- 无交集

# 去重(最常用场景)
items = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(items))
print(unique)  # [1, 2, 3, 4] --- 注意顺序可能变化

三、其它基础要点

3.1 真值测试(布尔上下文)

以下对象在布尔上下文中被视为 False(Falsy),其余均视为 True(Truthy):

python 复制代码
# 所有 Falsy 值
falsy_values = [
    False,
    None,
    0, 0.0, 0j,           # 数字零值
    "",                    # 空字符串
    (),                    # 空元组
    [],                    # 空列表
    {},                    # 空字典
    set(),                 # 空集合
    frozenset(),           # 空不可变集合
]

for v in falsy_values:
    print(f"{repr(v):15} → {bool(v)}")

# 利用真值测试简化代码
name = user_input or "默认名字"           # user_input 为空时用默认值
items = data and data.get("items") or []  # 安全获取嵌套数据

3.2 三元表达式

python 复制代码
age = 20
status = "成年" if age >= 18 else "未成年"
print(status)  # 成年

# 可嵌套但不建议(可读性差)
x = "正" if num > 0 else ("零" if num == 0 else "负")

3.3 *** 解包运算符

python 复制代码
# * 解包可迭代对象为位置参数
print(*[1, 2, 3])               # 等价于 print(1, 2, 3)

# ** 解包字典为关键字参数
def greet(name, age):
    print(f"{name}, {age}岁")

greet(**{"name": "Alice", "age": 25})  # 等价于 greet(name="Alice", age=25)

# 合并列表 / 字典(创建新对象,不修改原对象)
list1, list2 = [1, 2], [3, 4]
combined_list = [*list1, *list2]
print(combined_list)           # [1, 2, 3, 4]

dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}       # 注意 "b" 重复
merged = {**dict1, **dict2}     # 后者覆盖前者
print(merged)                  # {'a': 1, 'b': 3, 'c': 4}

3.4 type() 与 isinstance()

python 复制代码
class Animal:
    pass

class Dog(Animal):
    pass

d = Dog()

print(type(d))           # <class '__main__.Dog'>
print(type(d) == Dog)    # True
print(type(d) == Animal) # False --- 不匹配父类

print(isinstance(d, Dog))    # True
print(isinstance(d, Animal)) # True --- 子类属于父类实例
# ✅ 推荐多用 isinstance,它正确处理继承关系
相关推荐
weikecms1 小时前
外卖霸王餐API接口对接
大数据·人工智能·企业微信·微客云
仅此,1 小时前
deep agent整合 DeepSeek 记录
python·langchain·agent·deep agent sdk
captain_AIouo2 小时前
Captain AI以数据为核心,打造OZON智能决策引擎
大数据·人工智能·经验分享·aigc
ftpeak2 小时前
AI开发之LangGraph教程6~自定义状态 (Custom State)
python·ai·langchain·langgraph
星夜夏空992 小时前
STM32单片机学习(3)——前置知识学习
stm32·单片机·学习
m0_738120722 小时前
渗透测试——Djinn1靶场详细渗透提权过程讲解(绕过黑名单限制,命令执行反弹shell,pyc反编译,代码白盒分析,python沙盒逃逸)
开发语言·python·php
Aloudata2 小时前
AI 时代如何通过主动元数据构建高质量、可追溯的语义底座?
大数据·人工智能·数据治理·元数据·数据血缘
andafaAPS2 小时前
安达发|aps自动排产排程排单软件:日化生产高效运转“数字魔法”
大数据·人工智能·算法·aps软件·安达发aps·aps自动排产排程排单软件
黎阳之光3 小时前
全域实景立体管控:数字孪生与视频孪生技术体系白皮书
大数据·人工智能·算法·安全·数字孪生