Python中通过lambda表达式构造更复杂的defaultdict

在Python中需要初始化字典的时候我一般会调用collections中的defaultdict来实现,这样可以减少代码行数,并且避免更复杂的逻辑判断,比如:

a_list = ['a', 'b', 'c', 'a', 'd']

# 常规方法
count_dict = {}
for a in a_list:
    if a in count_dict:
        count_dict[a] += 1
    else:
        # 如果dict中不存在该key,则需要赋值来初始化
        count_dict[a] = 1

# 使用defaultdict进行初始化只需要4行代码,且不需要if...else进行逻辑判断
import collections
count_dict = collections.defaultdict(int)
for a in a_list:
    count_dict[a] += 1

defaultdict在Python 2.5中首次引入,它的第一个参数可以是工厂函数,将以无参数的形式给字典中的key初始化默认值。比如上例中为int(),则key的值将被初始化为0。和int类似,其他诸如listtuplesetdict等工厂函数也可以用来初始化,分别对应空的链表、元组、集合和字典。

不过实际编程中经常遇到更复杂的情况,比如字典嵌套字典,简单的内置工厂函数不够用。我以前可能就直接自己写逻辑判断进行初始化了,耗时费脑不说还可能写错。其实最好的方法就是用lambda表达式快速构造一个无需参数的函数,简单且灵活。因为defaultdict的第一个参数除了可以是工厂函数外(本质是类),也可以是自己构建的函数。

下例中我构建了一个variant_dict用来储存基因组变异类型,然后从中分别统计杂合和纯合SNP、Del、Ins的数量:

>>> import collections
>>> variant_dict = {
        'variant_1' : ('SNP', 'het'), 
        'variant_2' : ('SNP', 'homo'), 
        'variant_3' : ('Del', 'homo'), 
        'variant_4' : ('Ins', 'het')
    }

>>> count_dict = collections.defaultdict(lambda : {'het':0, 'homo':0})
>>> for k, v in variant_dict.iteritems():
        count_dict[v[0]][v[1]] += 1

>>> print count_dict
defaultdict(<function <lambda> at 0x0000000003983B38>, {'Del': {'het': 0, 'homo': 1}, 'SNP': {'het': 1, 'homo': 1}, 'Ins': {'het': 1, 'homo': 0}})

标签: Python, 编程, 基因组

知识共享许可协议 作者: 链接:https://byteofbio.com/archives/20.html
本文采用“署名-非商业性使用-相同方式分享 4.0 国际许可协议”进行许可

暂无评论

添加新评论