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)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容