先说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)