Python 内置数据类型完全参考

Python 整数无大小限制,自动支持大整数运算。 返回表示该整数所需的二进制位数(不含符号位和前导零)。 返回整数二进制表示中 1 的个数(汉明重量)。 返回 (numerator, denominator) 使分数等价于该整数,分母为 1。 始终返回 True。为与 float.is_integer() 进行鸭子类型兼容而存在。 基于 IEEE 754 双精度(64 位)。 判断浮点值是否为整数(无小数部分)。 返回 IEEE 754 十六进制字符串表示。用于精确序列化浮点数。 从 hex() 返回的字符串还原浮点数,可跨平台精确还原。 返回分子/分

分享

官方文档:https://docs.python.org/3/library/stdtypes.html
适用版本:Python 3.13(2026-05-07 核实)


1. int 整数

Python 整数无大小限制,自动支持大整数运算。

常用方法

int.bit_length() -> int

返回表示该整数所需的二进制位数(不含符号位和前导零)。

(37).bit_length()   # 6,因为 37 = 0b100101
(0).bit_length()    # 0
(-1).bit_length()   # 1

int.bit_count() -> int (Python 3.10+)

返回整数二进制表示中 1 的个数(汉明重量)。

(12).bit_count()    # 2,因为 12 = 0b1100

int.to_bytes(length=1, byteorder='big', *, signed=False) -> bytes

Python 3.11+ 起 lengthbyteorder 有默认值;3.10 及以前两者均为必填参数。

参数 类型 默认值 说明
length int 1(3.11+) 输出字节数,必须足够大否则 OverflowError
byteorder str 'big'(3.11+) 'big'(高位在前)或 'little'(低位在前)
signed bool False True 允许负数;False 时负数报错
(1024).to_bytes(2, 'big')              # b'\x04\x00'
(1024).to_bytes(2, 'little')           # b'\x00\x04'
(-1).to_bytes(2, 'big', signed=True)   # b'\xff\xff'
(65).to_bytes()                        # b'A'(Python 3.11+,使用默认值)

int.from_bytes(bytes, byteorder='big', *, signed=False) -> int (类方法)

Python 3.11+ 起 byteorder 有默认值;3.10 及以前为必填参数。

参数 类型 默认值 说明
bytes bytes-like 要解析的字节序列(也支持可迭代的整数)
byteorder str 'big'(3.11+) 'big''little'
signed bool False True 按有符号整数解析
int.from_bytes(b'\x04\x00', 'big')              # 1024
int.from_bytes(b'\xff\xff', 'big', signed=True)  # -1
int.from_bytes([255, 0, 0], 'big')              # 16711680(支持整数可迭代对象)

int.as_integer_ratio() -> tuple[int, int] (Python 3.8+)

返回 (numerator, denominator) 使分数等价于该整数,分母为 1。

int.is_integer() -> bool (Python 3.12+)

始终返回 True。为与 float.is_integer() 进行鸭子类型兼容而存在。

(3).is_integer()   # True

实用场景

  • 位运算、权限掩码:perms = READ | WRITE
  • 网络协议编解码(配合 to_bytes / from_bytes
  • 大整数计算(无溢出)

注意事项

  • //(整除)结果始终为 int/(真除)结果始终为 float
  • int('0xff', 16)int('0b1010', 2) 支持进制转换

2. float 浮点数

基于 IEEE 754 双精度(64 位)。

常用方法

float.is_integer() -> bool

判断浮点值是否为整数(无小数部分)。

(3.0).is_integer()   # True
(3.5).is_integer()   # False

float.hex() -> str

返回 IEEE 754 十六进制字符串表示。用于精确序列化浮点数。

(3.14).hex()   # '0x1.91eb851eb851fp+1'

float.fromhex(s) -> float (类方法)

hex() 返回的字符串还原浮点数,可跨平台精确还原。

float.fromhex('0x1.91eb851eb851fp+1')   # 3.14

float.as_integer_ratio() -> tuple[int, int]

返回分子/分母对,精确表示该浮点值。

(0.25).as_integer_ratio()   # (1, 4)

精度问题

0.1 + 0.2 == 0.3   # False!
# 金融场景用 decimal.Decimal
from decimal import Decimal
Decimal('0.1') + Decimal('0.2') == Decimal('0.3')  # True

math 模块常用函数

import math
math.floor(x)   # 向下取整 → int
math.ceil(x)    # 向上取整 → int
math.trunc(x)   # 截断小数 → int
math.isnan(x)   # 是否 NaN
math.isinf(x)   # 是否无穷大

3. str 字符串

不可变序列,每次"修改"都创建新对象。

完整参考:str 方法文档

大小写变换

str.lower() -> str / str.upper() -> str

全部转小/大写。

'Hello'.lower()   # 'hello'

str.casefold() -> str

更激进的小写转换,适合 Unicode 语言的大小写无关比较(德语 ß → ss)。

str.capitalize() -> str

首字母大写,其余小写。

str.title() -> str

每个单词首字母大写。

str.swapcase() -> str

大小写互换。

去除空白/字符

str.strip(chars=None) -> str

参数 说明
chars 要去除的字符集合(不是子串!),None 表示去除所有空白符
'  hello  '.strip()         # 'hello'
'xxxhelloxxx'.strip('x')    # 'hello'
'xyzhellozyx'.strip('xyz')  # 'hello'  # 去除集合中的任意字符

str.lstrip(chars=None) -> str / str.rstrip(chars=None) -> str

只去左侧 / 只去右侧。

str.removeprefix(prefix) -> str (Python 3.9+)

str.removesuffix(suffix) -> str (Python 3.9+)

如果匹配则去除,否则原样返回(比 lstrip 更精确,是子串匹配)。

'test_file.py'.removesuffix('.py')   # 'test_file'

替换

str.replace(old, new, /, count=-1) -> str

参数 说明
old 被替换的子串
new 替换为的子串
count 最多替换次数,-1(默认)表示全部替换;Python 3.13+ 起支持关键字传参
'aabbaabb'.replace('aa', 'X')            # 'XbbXbb'
'aabbaabb'.replace('aa', 'X', 1)         # 'Xbbaabb'
'aabbaabb'.replace('aa', 'X', count=1)   # Python 3.13+:count 可用关键字传入

str.translate(table) -> str

批量字符映射,比 replace 高效(一次遍历完成多个替换)。

# 删除标点
import string
table = str.maketrans('', '', string.punctuation)
'hello, world!'.translate(table)   # 'hello world'

# 字符替换
table = str.maketrans('aeiou', '12345')
'hello'.translate(table)   # 'h2ll4'

str.maketrans(x, y=None, z=None) -> dict (静态方法)

参数 说明
x 若单独提供,必须是 {char: replacement} 字典;或与 y 配对的字符集
y x 等长的替换字符集
z 要删除的字符集合

分割

str.split(sep=None, maxsplit=-1) -> list[str]

参数 说明
sep 分隔符,None 表示按连续空白分割(并忽略首尾空白)
maxsplit 最大分割次数,-1 表示不限制
'a b  c'.split()           # ['a', 'b', 'c']
'a,b,c'.split(',')         # ['a', 'b', 'c']
'a,b,c'.split(',', 1)      # ['a', 'b,c']
',a,'.split(',')           # ['', 'a', '']  # 注意首尾空串!

str.rsplit(sep=None, maxsplit=-1) -> list[str]

从右侧开始分割,参数同 split

'a.b.c'.rsplit('.', 1)   # ['a.b', 'c']  # 常用于取文件扩展名

str.splitlines(keepends=False) -> list[str]

参数 说明
keepends True 则保留行尾换行符

\n\r\n\r 等各种换行符分割。

str.partition(sep) -> tuple[str, str, str]

在第一个 sep 处分成三段 (before, sep, after),找不到则 (original, '', '')

'[email protected]'.partition('@')   # ('user', '@', 'example.com')

str.rpartition(sep) -> tuple[str, str, str]

从右侧找第一个 sep

拼接

str.join(iterable) -> str

str 作分隔符拼接 iterable 中的字符串。

', '.join(['a', 'b', 'c'])   # 'a, b, c'
''.join(['h', 'e', 'l', 'l', 'o'])   # 'hello'

最佳实践:批量拼接用 ''.join(list) 而非 +=,后者是 O(n²)。

查找

str.find(sub, start=0, end=None) -> int

参数 说明
sub 要查找的子串
start 搜索起始位置(包含)
end 搜索结束位置(不含)

返回第一次出现的索引,找不到返回 -1

str.rfind(sub, start=0, end=None) -> int

从右侧开始查找,参数同 find

str.index(sub, start=0, end=None) -> int

find 但找不到抛出 ValueError

str.rindex(sub, start=0, end=None) -> int

从右侧开始,找不到抛 ValueError

str.count(sub, start=0, end=None) -> int

统计子串出现次数(不重叠)。

'aaaa'.count('aa')   # 2(不重叠)

判断

str.startswith(prefix, start=0, end=None) -> bool

参数 说明
prefix 字符串或字符串元组(只要匹配其一即返回 True
start / end 搜索范围
'hello.py'.startswith(('.py', '.txt'))  # False,检测后缀应用 endswith
'hello.py'.endswith(('.py', '.txt'))    # True

str.endswith(suffix, start=0, end=None) -> bool

参数同 startswith

str.isdigit() -> bool

全为 Unicode 数字字符(含上标等)。

str.isdecimal() -> bool

全为十进制数字(比 isdigit 更严格,不含上标)。

str.isnumeric() -> bool

最宽松,含罗马数字、分数字符等。

str.isalpha() -> bool / str.isalnum() -> bool

全字母 / 全字母或数字。

str.isidentifier() -> bool

是否是合法 Python 标识符。

str.isspace() -> bool

全为空白字符。

格式化

str.format(*args, **kwargs) -> str

'{name} 是 {age} 岁'.format(name='Alice', age=30)
'{0} + {1} = {2}'.format(1, 2, 3)
'{:.2f}'.format(3.14159)   # '3.14'

str.format_map(mapping) -> str

类似 format(**mapping) 但不复制字典,支持缺失键的自定义处理。

f-string(推荐,Python 3.6+)

name = 'Alice'
f'{name!r}'        # 使用 repr()
f'{value:.2f}'     # 格式说明符
f'{expr = }'       # Python 3.8+ 调试输出:'expr = value'

对齐/填充

str.center(width, fillchar=' ') -> str

str.ljust(width, fillchar=' ') -> str

str.rjust(width, fillchar=' ') -> str

参数 说明
width 输出总宽度,若原字符串已超出则原样返回
fillchar 填充字符,必须是单个字符

str.zfill(width) -> str

左侧补零,正确处理符号位。

'42'.zfill(5)    # '00042'
'-42'.zfill(5)   # '-0042'

编码

str.encode(encoding='utf-8', errors='strict') -> bytes

参数 说明
encoding 编码名称,如 'utf-8''gbk''ascii'
errors 错误处理:'strict'(默认,报错)、'ignore''replace''xmlcharrefreplace'

4. list 列表

可变有序序列。

常用方法

list.append(x)

在尾部追加单个元素。时间复杂度 O(1) 均摊。

lst = [1, 2]
lst.append(3)   # [1, 2, 3]

list.extend(iterable)

批量追加,等价于 +=

lst.extend([4, 5])   # [1, 2, 3, 4, 5]

注意:append([4, 5]) 会把列表作为一个元素加入,而 extend([4, 5]) 才是展开追加。

list.insert(i, x)

参数 说明
i 插入位置;超出范围不报错(i >= len 等价于 appendi < 0 从头算起)
x 插入的元素
lst.insert(0, 0)    # 在头部插入
lst.insert(100, 9)  # 等价于 append

注意:中间插入是 O(n),频繁插入头部应用 collections.deque

list.remove(x)

删除第一个值等于 x 的元素,找不到抛 ValueError

list.pop(i=-1) -> element

参数 说明
i 弹出位置,默认 -1(尾部);负数从尾算起
lst.pop()    # 弹出最后一个,O(1)
lst.pop(0)   # 弹出第一个,O(n),频繁操作用 deque

list.index(x, start=0, end=None) -> int

返回第一个等于 x 的索引,找不到抛 ValueError

list.count(x) -> int

统计 x 出现次数。

list.sort(*, key=None, reverse=False)

参数 说明
key 提取排序键的函数,None 直接比较元素
reverse True 则降序

原地排序,返回 None(区别于 sorted() 返回新列表)。

lst.sort(key=lambda x: x['age'], reverse=True)
lst.sort(key=str.lower)   # 大小写不敏感排序

使用 Timsort 算法,稳定排序,时间复杂度 O(n log n)。

list.reverse()

原地反转,O(n),返回 None

list.copy() -> list

浅拷贝(等价于 lst[:]),嵌套对象仍共享引用。

list.clear()

删除所有元素(等价于 del lst[:])。

切片操作

lst[start:stop:step]   # 创建新列表
lst[::-1]               # 反转(浅拷贝)
lst[1:3] = [10, 20]    # 切片赋值(可改变长度)
del lst[1:3]            # 切片删除

推导式(最佳实践)

# 比 map/filter 更 Pythonic
squares = [x**2 for x in range(10) if x % 2 == 0]
flat = [x for row in matrix for x in row]   # 展平二维列表

5. tuple 元组

不可变有序序列。一旦创建不可修改。

方法

  • tuple.count(x) -> int:统计 x 出现次数
  • tuple.index(x, start=0, end=None) -> int:查找索引

核心用途

  • 函数多返回值:return x, y
  • 作为 dict 的键(列表不可)
  • 命名元组(collections.namedtuple / typing.NamedTuple

注意

# 单元素元组必须加逗号
single = (1,)   # tuple
not_tuple = (1)  # 只是括号,结果是 int

6. dict 字典

可变键值映射,Python 3.7+ 保证插入顺序。

常用方法

dict.get(key, default=None) -> value

参数 说明
key 要查找的键
default 键不存在时的返回值,默认 None
d = {'a': 1}
d.get('b', 0)   # 0,不报 KeyError

dict.setdefault(key, default=None) -> value

如果 key 不存在,则插入 key: default 并返回 default;已存在则返回已有值(不修改)。

d.setdefault('count', 0)
d['count'] += 1   # 安全计数
# 常见模式:构建反向索引
for word, idx in data:
    d.setdefault(word, []).append(idx)

dict.update(other=None, **kwargs)

用另一个字典或关键字参数更新(合并),已存在的键会被覆盖。

d.update({'b': 2}, c=3)
# Python 3.9+ 合并运算符
merged = d1 | d2       # 新字典
d1 |= d2               # 原地更新

dict.pop(key, default=_missing) -> value

参数 说明
key 要删除的键
default 键不存在时的返回值;不提供则键不存在时抛 KeyError
d.pop('key', None)   # 安全删除

dict.popitem() -> (key, value)

删除并返回最后插入的键值对(Python 3.7+ 有序)。字典为空时抛 KeyError

dict.keys() -> dict_keys / dict.values() -> dict_values / dict.items() -> dict_items

返回视图对象,动态反映字典变化,支持集合操作。

# 视图支持集合运算
d1.keys() & d2.keys()   # 共同键
d1.items() - d2.items() # 差异项

dict.copy() -> dict

浅拷贝。

dict.clear()

清空字典。

dict.fromkeys(iterable, value=None) -> dict (类方法)

参数 说明
iterable 作为键的可迭代对象
value 所有键的初始值(共享同一对象!可变类型要小心)
dict.fromkeys(['a', 'b', 'c'], 0)   # {'a': 0, 'b': 0, 'c': 0}
# 陷阱:
dict.fromkeys(['a', 'b'], [])       # 两个键共享同一个列表!

推导式

{k: v for k, v in items if v > 0}
{v: k for k, v in d.items()}   # 反转字典

collections.defaultdict

from collections import defaultdict
dd = defaultdict(list)
dd['key'].append(1)   # 不需要先初始化

collections.Counter

from collections import Counter
c = Counter('hello')   # Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
c.most_common(2)       # [('l', 2), ('h', 1)]
c.update('world')      # 累加计数

7. set / frozenset 集合

可变无序唯一集合 / 不可变版本。

常用方法

set.add(x)

添加元素,已存在不报错。

set.remove(x)

删除元素,不存在抛 KeyError

set.discard(x)

删除元素,不存在不报错(比 remove 更安全)。

set.pop() -> element

弹出任意元素(集合无序)。

set.update(*others) / |=

并集(原地)。

set.intersection_update(*others) / &=

交集(原地)。

set.difference_update(*others) / -=

差集(原地)。

set.symmetric_difference_update(other) / ^=

对称差集(原地,即"只在一方出现"的元素)。

集合运算(返回新集合)

操作符 方法 说明
| union(*others) 并集
& intersection(*others) 交集
- difference(*others) 差集(在自身不在 other)
^ symmetric_difference(other) 对称差集
a = {1, 2, 3}
b = {2, 3, 4}
a | b   # {1, 2, 3, 4}
a & b   # {2, 3}
a - b   # {1}
a ^ b   # {1, 4}

子集/超集判断

方法 操作符 说明
issubset(other) <= 是否为子集(含相等)
issuperset(other) >= 是否为超集
isdisjoint(other) 是否无交集

<> 操作符表示真子集/真超集(不含相等)。

注意事项

  • 集合元素必须可哈希(不可变),列表不行,元组可以
  • frozenset 可作为 dict
  • 推导式:{x for x in iterable}

8. bytes / bytearray

bytes 不可变,bytearray 可变。

创建

b'\x00\xff'                  # 字面量
bytes(10)                    # 10 个零字节
bytes([65, 66, 67])          # b'ABC'
bytes('hello', 'utf-8')      # 等同于 'hello'.encode('utf-8')
bytearray(b'hello')          # 可变版本

常用方法

bytes.decode(encoding='utf-8', errors='strict') -> str

参数 说明
encoding 解码使用的编码,默认 'utf-8'
errors 错误处理策略:'strict''ignore''replace''backslashreplace'
b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')   # '中文'
b'\xff'.decode('utf-8', errors='ignore')        # ''(忽略无效字节)

bytes.hex(sep=None, bytes_per_sep=None) -> str (Python 3.8+ 支持参数)

参数 说明
sep 分隔符字符
bytes_per_sep 每隔多少字节插入分隔符(负数从右算)
b'\xde\xad\xbe\xef'.hex()           # 'deadbeef'
b'\xde\xad\xbe\xef'.hex(':', 2)     # 'de:ad:be:ef'

bytes.fromhex(string) -> bytes (类方法)

从十六进制字符串创建 bytes。

bytes.fromhex('deadbeef')   # b'\xde\xad\xbe\xef'

bytes.find(sub, start=0, end=None) -> int

查找子序列,参数同 str.find

bytes.split(sep=None, maxsplit=-1) -> list[bytes]

参数同 str.split

常用场景

  • HTTP 原始请求/响应解析
  • 加密算法输入/输出
  • 文件 IO(图片、二进制数据)
  • JS 逆向中还原二进制协议

9. range

只读序列,极省内存(只存起止和步长)。

range(stop) / range(start, stop, step=1)

参数 说明
start 起始值(含),默认 0
stop 终止值(不含)
step 步长,默认 1,可以为负数
range(5)          # 0,1,2,3,4
range(1, 10, 2)   # 1,3,5,7,9
range(10, 0, -1)  # 10,9,...,1

属性和方法

  • .start / .stop / .step:参数值
  • r.index(x) / r.count(x):和 list 同名方法
  • 支持 len()inreversed()、切片(返回新 range

最佳实践

# 分页
for page in range(0, total, page_size):
    fetch(offset=page, limit=page_size)

# 带索引遍历(用 enumerate 更好)
for i, v in enumerate(items):
    ...

10. bool

boolint 的子类,True == 1False == 0

真值判断规则

以下对象在 bool() 时为 False

  • NoneFalse
  • 数值零:00.00jDecimal(0)
  • 空容器:''[]{}()set()
  • 实现了 __bool__ 返回 False__len__ 返回 0 的对象
# 利用真值判断
if items:            # 比 if len(items) > 0 更 Pythonic
    process(items)

result = value or default   # value 为假时用 default
safe = value and value.attr # value 为假时短路,不访问 .attr

类型转换速查

目标类型 函数 示例
int int(x, base=10) int('ff', 16)255
float float(x) float('3.14')3.14
str str(x) str(123)'123'
list list(iterable) list('abc')['a','b','c']
tuple tuple(iterable)
set set(iterable)
dict dict(mapping) / dict(**kw) dict(a=1){'a': 1}
bytes bytes(str, encoding)
bool bool(x)

可变 vs 不可变总结

类型 可变 可哈希(可作键) 有序
list
dict ✅(3.7+)
set
bytearray
str
tuple ✅(含可哈希元素时)
int/float/bool
bytes
frozenset

常见陷阱

陷阱:+= 对列表与元组行为不同

现象: a += [1]list 原地修改,对 tuple 会创建新对象,导致其他持有该引用的变量看到不同结果。
原因: list.__iadd__ 调用 extend 原地修改,tuple__iadd__+= 等价于 a = a + (1,) 创建新对象。
解决: 了解可变/不可变语义。需要就地修改序列,用 list;需要不可变序列,用 tuple 并避免 +=

陷阱:浮点数比较精度问题

现象: 0.1 + 0.2 == 0.3 返回 False,浮点运算结果与预期不符。
原因: 浮点数用 IEEE 754 二进制表示,大多数十进制小数无法精确表示,累计误差导致比较失败。
解决:math.isclose(a, b, rel_tol=1e-9) 比较浮点数;货币计算用 decimal.Decimal

import math
math.isclose(0.1 + 0.2, 0.3)  # True

from decimal import Decimal
Decimal('0.1') + Decimal('0.2') == Decimal('0.3')  # True

陷阱:dict 默认值共享引用

现象: d = {'a': [], 'b': []}; d['a'].append(1)d['b'] 没变,但用 dict.fromkeys 初始化时所有键共享同一列表。
原因: dict.fromkeys(['a', 'b'], []) 所有键的 value 指向同一个列表对象。
解决: 用字典推导式确保每个键得到独立对象:

# 错误:所有键共享同一列表
d = dict.fromkeys(['a', 'b'], [])
d['a'].append(1)  # d['b'] 也变了!

# 正确
d = {k: [] for k in ['a', 'b']}

参见

asyncio异步编程完全指南
Python/基础/装饰器与函数高级

阅读更多

Web 安全基础

1. HTML 转义(服务端渲染必须): 2. CSP(Content Security Policy): 3. HttpOnly Cookie:防止 JS 读取会话 Cookie: 4. 前端框架防护: 攻击者在第三方网站构造一个表单,诱导已登录用户提交,浏览器会自动携带目标站的 Cookie。 触发条件: 1. 用户已登录目标网站(Cookie 有效) 2. 目标 API 仅凭 Cookie 识别用户身份 3. 请求来源未验证 1. CSRF Token(推荐): 2. SameSite Cookie: 3. 验证 Origin/Referer 头:

By yellowdog

HTTP 协议深度指南

HTTP(HyperText Transfer Protocol)是 Web 的基础传输协议,基于 TCP/IP,采用请求/响应模型。 相关文档:Web安全基础(/web-an-quan-ji-chu/) FastAPI完全指南(/fastapi-wan-quan-zhi-nan/) Nginx完全指南(/nginx-wan-quan-zhi-nan/) 幂等性:多次执行相同请求,服务器状态结果相同。PUT /users/1 多次执行结果一致;POST /users 每次创建新资源,非幂等。 浏览器直接从本地缓存读取,不向服务器发送请求。 缓存命中时,状

By yellowdog

系统设计基础

SLA 对照表: 选择建议:无状态服务(Web 层、API 层)优先水平扩展;数据库初期垂直扩展,达到瓶颈后考虑分库分表或读写分离。 缓存穿透(查询不存在的 key,每次都打到 DB): 缓存击穿(热点 key 过期,瞬间大量请求打到 DB): 缓存雪崩(大量 key 同时过期,或缓存服务宕机): 令牌桶 Python 实现: Redis 实现分布式限流(滑动窗口): URL 命名规则: Cursor 分页响应格式: 雪花算法结构(64 bit): 定义:分布式系统不能同时满足以下三个特性: 在分布式环境中 P 是必须保证的,所以实际是 CP vs AP

By yellowdog

算法思路与模板

二分查找要求序列有序,每次将搜索范围缩减一半,时间复杂度 O(log n)。 两个指针从两端向中间收缩,常用于有序数组。 滑动窗口维护一个满足条件的区间 left, right,right 不断向右扩张,条件不满足时收缩 left。 滑动窗口通用框架: 1. 确定"子问题":原问题可以分解为哪些规模更小的同类问题 2. 定义 dpi 或 dpij 的含义,要足够清晰 3. 推导状态转移方程 4. 确定初始状态(边界条件) 5. 确定计算顺序(确保依赖的子问题先计算) 每件物品最多选一次。dpj = 容量为 j 时的最大价值,逆序遍历容量防止重复选取。 每

By yellowdog