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