px普贤教程PuXian
普贤教程 › 基础教程

字典

字典是键值容器:键是字符串,值可以是任意类型。它在 PuXian 里承担的角色比在 Python 里更重——JSON、配置、请求上下文都用字典表达。

创建与访问

px
var user = {"name": "晨曦", "role": "QA", "age": 1}
print(user["name"])
print(str(len(user)))
text
晨曦
3

len() 返回键的个数。

写入与修改

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.kR1007 没有字段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