key value容器的默认值

先说stl里的map。
比如我们有一个这样的数据结构,map<string, int> str_map。之后我们需要统计一段文本中,每个字符串出现的次数,假设这个文本以字符串数组的形式存储在vector中。
代码如下:

map<string, int> str_map;
vector<string> input_txt;

for (unsigned int i = 0; i < input_txt.size(); i++)
{
    if (str_map.end() == str_map.find(input_txt[i]))
    {
        str_map[input_txt[i]] = 1;
    }
    
    else
    {
        str_map[input_txt[i]]++;
    }
}

但是,这样写起来很不方便。其实上面的那个if判断完全可以去掉,写成这样:

for (unsigned int i = 0; i < input_txt.size(); i++)
{
    str_map[input_txt[i]]++;    
}

主要原因就是map的[]操作在没有找到key的情况下,会生成一个默认的value值(int的默认值为0),进行填充,并返回其引用。[]的实现如下:

mapped_type& operator[](const key_type& _Keyval)
{    
    // find element matching _Keyval or insert with default mapped
    iterator _Where = this->lower_bound(_Keyval);
    if (_Where == this->end()
        || this->comp(_Keyval, this->_Key(_Where._Mynode())))
            _Where = this->insert(_Where, value_type(_Keyval, mapped_type()));
            
    return ((*_Where).second);
}

然后是python中的字典。
传统的写法:

str_dic = {}
for i in input_txt:
    if (i in str_dic):
        str_dic[i] += 1
    else:
        str_dic[i] = 1

如果像c++那样的简化版那样省掉if判断,是不可以的。因为python是动态语言,编译器无法知道dic的默认类型。
这时有2种解决方式。
1 使用dict的setdefault操作,代码如下:

for i in input_txt:
    str_dic.setdefault(i, 0)
    str_dic[i] += 1

当然了,还有更简洁的方式,如下:

for i in input_txt:
    str_dic[i] = str_dic.setdefault(i, 0) + 1

其实,使用默认值,还有一种方式,就是通过collections中的defaultdict来实现,可以使用一个类型或者函数来设置dict的默认值。代码如下:

from collections import defaultdict
str_dic = defaultdict(int)
#or str_dic = defaultdict(lambda:0)
for i in input_txt:
    str_dic[i] += 1

(原文时间2015-3-19)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容