如何用紧凑方式获取多字符串的唯一字符集合?
问题
给定如下唯一键列表:
idx_keys = [ "1996/a/50/18_supp__323:5", "1996/a/50/18_supp__326:1", "1996/a/50/18_supp__368:2", "1996/a/50/18_supp__907:1", "1996/a/c_2/51/sr_37_164:1", ]
目标是提取所有键包含的唯一字符集合。目前已通过循环实现需求:
chars = set() for k in idx_keys: chars = chars.union(k) print(chars) print(f"{'-' in chars = }") # -> False print(f"{'_' in chars = }") # -> True
但尝试用集合推导式时触发TypeError:
print({set(k) for chars in idx_keys}) # -> TypeError: unhashable type: 'set'
现寻求更紧凑的实现方式(例如使用海象运算符),要求逻辑能适配任意嵌套可迭代对象的并集操作,可读性欠佳也可接受。
解决方案
1. 海象运算符实现
用海象:=在表达式内完成集合初始化与更新,一行搞定:
(chars := set()).update(*idx_keys) print(chars)
若要处理嵌套可迭代对象(比如列表里包含子列表/元组),先通过itertools.chain扁平化结构再传入update:
from itertools import chain # 示例嵌套结构 nested_idx = ["abc", ["def", "ghi"], ("jkl", "mno")] (chars := set()).update(*chain.from_iterable(nested_idx))
2. 原生简洁写法
无需海象,利用set.union的可变参数特性直接生成结果:
chars = set().union(*idx_keys)
适配嵌套结构时同样先扁平化:
from itertools import chain nested_idx = ["abc", ["def", "ghi"], ("jkl", "mno")] chars = set().union(*chain.from_iterable(nested_idx))
3. 正确的集合推导式写法
之前的推导式报错是因为试图把set对象作为外层集合的元素(集合元素必须可哈希,而set不可哈希)。正确的写法应该直接遍历每个字符:
chars = {c for k in idx_keys for c in k}
适配嵌套结构只需多加一层循环:
nested_idx = ["abc", ["def", "ghi"], ("jkl", "mno")] chars = {c for iter_obj in nested_idx for k in iter_obj for c in k}
内容的提问来源于stack exchange,提问作者Anil
相关产品推荐
相关产品推荐

