2014-11-03 62 views
1

在python中,dict(zip(values ...))的最佳替代選擇是什麼?什麼是最好的C++替代python字典和zip?

我現在在休息時間正在爲一位C++學生輔導,並且在我的工作中遇到了一段Python代碼,發現我不知道最佳答案。

的代碼如下所示(我改變的變量名,並推廣了一點,但它是同樣的想法):

(dict(zip(wordCollection, [word.strip() for word in currentLine.split(',')][1:-1]))) 

我已經取代了剝離,並與分詞修剪,使用增強的標記化矢量,並且工作正常;然而,當我試圖決定翻譯字典/郵編組合的最佳方式時,我感到非常遺憾。

回答

2

你真的不應該試圖將習語直接從一種語言翻譯成另一種語言。在C++中,您通常不會編寫採用迭代器並生成新迭代器的函數;相反,你可以編寫帶有輸入和輸出迭代器的函數,並從一個複製到另一個。因此,您可以編寫一個zip函數,該函數採用T以上的輸入迭代器,通過U的輸入迭代器以及採用pair<T, U>以上的輸出迭代器。

但是,你不打算把這兩個調用以這種方式連接起來,因爲你的zip函數不會返回任何可以有用地傳遞給任何類型的dict函數的任何東西(比如迭代器範圍)。相反,您可以創建一個dict模擬(unordered_map),在其中創建輸出迭代器,並使用zip函數將對複製到其中。

事情是這樣的:

template <I1, I2, O> 
void zip(I1 it1, I1 it1end, I2 it2, I2 it2end, O o) { 
    while ((it1 != it1end) && (it2 != it2end)) { 
     *o++ = std::make_pair(*it1++, *it2++); 
    } 
} 

std::unordered_map<T, U> mapping; 
zip(c1.begin(), c1.end(), c2.begin(), c2.end(), std::inserter(mapping, mapping.end())); 

除了我不認爲你可以實際使用上unordered_map這樣或那樣不inserter,所以你必須寫一個map_inserter函數。

如果您不知道本地的各類TU,您可能希望以提取從元素類型的迭代器的類型,所以你可以auto它一個函數模板來包裝這一切了。 (在C++ 11,你可以decltype它不需要的功能,但表達將是一個爛攤子。)


如果你有一個zipmap_inserter多種用途,它可能是值得寫他們。但除此之外,一個更好的解決辦法是將它擴展到外在的循環:

auto it1 = c1.begin(), it1end = c1.end(), it2 = c2.begin(), it2end = c2.end(); 
std::unordered_map<T, U> mapping; 
while ((it1 != it1end) && (it2 != it2end)) { 
    mapping[*it1++] = *it2++; 
} 
+0

是的,我通常不會直接在實踐中做到這一點,我相信在不直接翻譯成語時也是如此。我只是好奇什麼是最好的和適當的「C++方式」來解決同樣的問題 – 2014-11-03 19:29:38

+0

我會寫非常不同的zip。我希望它像容器一樣,這樣的用法可以像'for(auto pr:zip(c1,c2)){...}'。我認爲這比OutputIterator風格的算法更有用。 – Barry 2014-11-03 19:40:38

+1

@Barry:我同意這樣的事情更有用,但他們並不真正適合STL算法的成語。 (順便說一句,我沒有捍衛STL算法的習慣,我一直喜歡它,直到我發現其他語言中的惰性列表和Python生成器之類的東西,並且注意到它不需要每隔一段時間就使用這些算法,很多腳手架,你可以一直使用它們...這是我不像以前那麼多使用C++的原因之一。 – abarnert 2014-11-03 19:41:59

0
dict(zip(labels,values)) ---> dict([("a",1),("b",0)]) ---> dict(a=1,b=0) 

一個字典只是一個哈希表...這簡直使標籤和值,其中標籤(或鑰匙)是wordCollection和標記化字符串值

這樣的哈希表可能是一個哈希表...雖然它可能會需要多行一旦你有你的矢量喜歡做它在C++

4

好:

std::vector<std::string> wordCollection; 
std::vector<std::string> splitWords; 

然後你可以迭代:

std::map<std::string, std::string> dict; // or std::unordered_map 
std::size_t minSize = std::min(wordCollection.size(), splitWords.size()); 
for (size_t i = 0; i != minSize; ++i) { 
    dict.insert(std::make_pair(wordCollection[i], splitWords[i])); 
} 
1

IMO,最好的C++替代了dictstd::unordered_map,這是一個哈希表,併爲zip,它是從D4128 ranges proposalranges::view::zip,爲該參考實現可以在github.com/ericniebler/range-v3訪問。

C++代碼11:

#include <string> 
#include <vector> 
#include <unordered_map> 
#include <range/v3/view/zip.hpp> 

int main() { 
    using namespace std; 
    using ranges::view::zip; 

    int ints[] = {1, 2, 3}; 
    vector<string> strings = {"a", "b"}; 
    unordered_map<int, string> dict(zip(ints, strings)); 
} 

我希望這打開了在未來的C++標準。

相關問題