CQL 教程/数据类型/容器类型

容器类型

掌握 CQL 的四种内置容器:列表、元组、字典与集合,以及解包与切片的进阶用法。

10.1列表

列表用方括号 [] 创建,元素有序、可重复、可修改,是 CQL 中最常用的容器。

cql
# 创建、索引与切片
水果 = ["苹果", "香蕉", "橙子"]
数字 = [1, 2, 3]
空列表 = []
打印(水果)          # ['苹果', '香蕉', '橙子']
打印(水果[0])       # 苹果(正索引从 0 开始)
打印(水果[-1])      # 橙子(负索引从末尾倒数)
打印(水果[1:3])     # ['香蕉', '橙子'](切片,含头不含尾)
打印(列表(范围(5))) # [0, 1, 2, 3, 4](配合内置函数创建)

列表方法既可以使用 Python 风格的名字,也可以使用 CQL 的中文方法名别名,二者完全等价:

cql
# 中文方法名别名:追加 与 排序
数据 = [3, 1, 2]
数据.追加(4)      # 等价于 数据.append(4)
数据.排序()       # 等价于 数据.sort()
打印(数据)        # [1, 2, 3, 4]

10.2元组

元组用圆括号 () 创建,元素有序、可重复,但创建后不可修改。单元素元组必须在末尾保留逗号。

cql
# 元组创建与访问
坐标 = (10, 20)
打印(坐标)           # (10, 20)
打印(坐标[0])        # 10
打印(坐标[-1])       # 20
单元素 = (5,)        # 注意逗号不能省略,否则是整数
打印(元组([1, 2, 3]))  # (1, 2, 3)(由列表转换)
提示:元组不可变,适合存放固定不变的数据,例如坐标、RGB 颜色值等。尝试修改元组会抛出 类型错误。

10.3字典

字典用花括号 {} 以「键: 值」形式创建,按键快速查找,键不可重复。

cql
# 字典创建与访问
学生 = {"小明": 90, "小红": 85}
打印(学生)                  # {'小明': 90, '小红': 85}
打印(学生["小明"])          # 90(按键取值)
学生["小刚"] = 77           # 新增键值对
打印(学生.获取("小李", 0))  # 0(键不存在时返回默认值)

字典的中文方法名别名:学生.键() 等价于 学生.keys();配合运行时函数 对象获取对象项目 可以更安全地访问:

cql
# 中文方法名别名:键 / 对象获取 / 对象项目
学生 = {"小明": 90}
打印(学生.键())                      # 等价于 学生.keys()
打印(对象获取(学生, "小明", 0))      # 等价于 学生.get("小明", 0) -> 90
打印(对象获取(学生, "小李", 0))      # 键不存在返回默认值 0
打印(对象项目(学生))                 # 等价于 学生.items()

字典支持解包合并:用 {**配置, **覆盖} 一次合并多个字典,后写的键覆盖先写的键。

cql
# 字典解包合并(双目标支持)
配置 = {"主机": "localhost"}
覆盖 = {"端口": 8080, "主机": "127.0.0.1"}
合并 = {**配置, **覆盖}
打印(合并)  # {'主机': '127.0.0.1', '端口': 8080}

10.4集合

集合用 集合(...) 创建,元素无序、不重复,常用于去重与集合运算。CQL 为集合方法提供了完整的中文方法名别名。

中文方法名等价 Python 方法说明
并集union返回两个集合的并集
交集intersection返回两个集合的交集
差集difference返回属于前者但不属于后者的元素
子集issubset判断一个集合是否为另一个的子集
添加add向集合添加一个元素
丢弃discard移除一个元素,不存在也不报错
cql
# 集合运算与中文方法名别名
集合甲 = 集合([1, 2, 3])
集合乙 = 集合([3, 4, 5])
集合丙 = 集合([1, 2])
打印(集合甲.并集(集合乙))   # 等价于 集合甲.union(集合乙) -> {1, 2, 3, 4, 5}
打印(集合甲.交集(集合乙))   # 等价于 集合甲.intersection(集合乙) -> {3}
打印(集合甲.差集(集合乙))   # 等价于 集合甲.difference(集合乙) -> {1, 2}
打印(集合丙.子集(集合甲))   # 等价于 集合丙.issubset(集合甲) -> 真
集合甲.添加(9)             # 等价于 集合甲.add(9)
集合甲.丢弃(2)             # 等价于 集合甲.discard(2)
打印(集合甲)               # {1, 3, 9}
提示:这些中文方法名在 Python 与 JavaScript 两个目标都会自动转译:Python 目标编译为原生方法调用(如 集合甲.union(集合乙)),JS 目标改写为 集合并集(集合甲, 集合乙) 等运行时函数。

10.5解包

多重赋值可以一次性交换或拆分多个变量。经典的斐波那契迭代写法就利用了 a, b = b, a + b 同时赋值,右侧先求值、再整体赋值。

cql
# 交换与迭代解包(参考 examples/fibonacci.cql)
a, b = 0, 1
序列 = []
循环 i 在 范围(10):
    序列.append(a)
    a, b = b, a + b   # 右侧同时求值,再整体赋给左侧
打印(序列)  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

列表元素也可以直接解包到多个变量,配合星号收集中间部分:

cql
# 列表解包
名字 = ["小明", "小红", "小刚"]
甲, 乙, 丙 = 名字
打印(甲, 乙, 丙)        # 小明 小红 小刚
头, *中间, 尾 = [1, 2, 3, 4, 5]
打印(头, 中间, 尾)      # 1 [2, 3, 4] 5(星号收集中间元素)

10.6切片

切片语法为 数据[起始:停止:步长],三个部分都可以省略,还支持负步长实现反转。

cql
# 切片与步长
数据 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
打印(数据[:4])      # [0, 1, 2, 3](取前 4 个)
打印(数据[6:])      # [6, 7, 8, 9](从 6 到末尾)
打印(数据[1:7:2])   # [1, 3, 5](起始 1 停止 7 步长 2)
打印(数据[::2])     # [0, 2, 4, 6, 8](每隔一个取一个)
打印(数据[::-1])    # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0](负步长反转)
提示:切片同样适用于字符串与元组。CQL 的切片在 JavaScript 目标由转译器改写为 .slice().filter() / .reverse() 实现,语义与 Python 保持一致。