普贤教程 › 基础教程
字典
字典是键值容器:键是字符串,值可以是任意类型。它在 PuXian 里承担的角色比在 Python 里更重——JSON、配置、请求上下文都用字典表达。
创建与访问
px
var user = {"name": "晨曦", "role": "QA", "age": 1} print(user["name"]) print(str(len(user)))
text
晨曦
3len() 返回键的个数。
写入与修改
px
var d = {} d["a"] = 1 d["b"] = 2 d["a"] = 10 print(str(d["a"])) print(str(len(d)))
text
10 2
缺键是错误,不是 null
px
var d = {"a": 1} print(str(d["b"]))
text
运行时错误: 错误 [R1008] 2:12: 字典没有键 'b'
这条设计让"拼错键名"立刻暴露。对外部数据(例如 JSON 响应)取值前,先判断:
px
def get_or(d, k, fallback): if d.has(k): return d[k] return fallback var resp = {"ok": true} print(get_or(resp, "message", "(无消息)")) print(str(get_or(resp, "ok", false)))
text
(无消息)
true遍历
px
var scores = {"语文": 90, "数学": 95, "英语": 88} for k in scores: print(k + ":" + str(scores[k])) var keys = scores.keys() print(str(len(keys))) print(str(sorted(keys)))
text
语文:90 数学:95 英语:88 3 [英语, 数学, 语文]
遍历顺序字典不保证顺序。
for k in d 与 d.keys() 得到的顺序可能与你插入的顺序不同;需要稳定顺序时先 sorted()。键、值与删除
px
var d = {"a": 1, "b": 2} print(str(d.keys())) print(str(d.values())) print(str(d.has("a"))) print(str(d.has("zzz"))) d.remove("a") print(str(len(d))) print(str(d.has("a")))
text
[a, b] [1, 2] true false 1 false
嵌套结构
真实数据几乎总是嵌套的。下面是一份用户档案:
px
var user = { "id": 1024, "name": "晨曦", "tags": ["qa", "px"], "meta": {"region": "cn-north", "level": 3} } print(str(user["id"])) print(user["tags"][1]) print(str(user["meta"]["level"])) print(str(len(user["tags"])))
text
1024 px 3 2
用字典做配置
px
let DEFAULTS = {"timeout": 30, "retries": 3, "verbose": false} def conf(over): var c = {} for k in DEFAULTS: c[k] = DEFAULTS[k] for k in over: c[k] = over[k] return c var c = conf({"timeout": 60}) print(str(c["timeout"])) print(str(c["retries"])) print(str(c["verbose"]))
text
60 3 false
用字典做计数
px
def word_freq(text): var freq = {} for w in split(text, " "): var k = trim(w) if len(k) == 0: continue if freq.has(k): freq[k] = freq[k] + 1 else: freq[k] = 1 return freq var f = word_freq("a b a c a b") print(str(f["a"])) print(str(f["b"])) print(str(f["c"]))
text
3 2 1
常见错误对照
| 写法 | 结果 | 正确写法 |
|---|---|---|
d["missing"] | R1008 字典没有键 | 先 d.has(k) |
keys(d) | R1001 未定义变量 | d.keys() |
if d:(想判断非空) | 与直觉不符 | len(d.keys()) > 0 |
d.k | R1007 没有字段 | d["k"] |
引用语义
px
var a = {"n": 1} var b = a b["n"] = 2 print(str(a["n"]))
text
2和列表一样,赋值共享同一份数据。函数收到字典参数后修改它,调用方能看到变化——这常被用来"返回多个值":
px
def split_name(full, out): var parts = split(full, " ") out["first"] = parts[0] out["last"] = parts[1] return out var box = {} split_name("Chen Xi", box) print(box["first"] + " / " + box["last"])
text
Chen / Xi