2

python 中 dict(zip(values...)) 的最佳 C++ 替代品是什么?

我正在辅导一个 C++ 学生,目前在我的课余时间,在我的工作中遇到了一段 Python 代码,发现我不知道最好的答案。

代码如下所示(我更改了变量的名称,并对其进行了一些概括,但这是相同的想法):

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

我已经使用 boost 用修剪过的标记化向量替换了剥离和拆分的单词,效果很好;但是,当我试图决定翻译 dict/zip 组合的最佳方式时,我不知所措。

4

4 回答 4

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]));
}
于 2014-11-03T19:26:25.877 回答
2

您真的不应该尝试将习语直接从一种语言翻译成另一种语言。

在 C++ 中,您通常不会编写带有迭代器并生成新迭代器的函数;相反,您编写的函数接受输入和输出迭代器并从一个迭代器复制到另一个。因此,您可以编写一个zip函数,它接受一个输入迭代器 over T、一个输入迭代器 overU和一个输出迭代器 over pair<T, U>

但是你不会以这种方式将两个调用链接在一起,因为你的zip函数不会返回任何可以有效传递给任何类型dict函数的东西(比如迭代器范围)。相反,您可以创建一个dict模拟 (an 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()));

除非我认为您实际上不能inserterunordered_map这种方式使用,因此您必须改为编写一个map_inserter函数。

如果您不知道类型TU本地,您可能希望将所有这些都包装在一个函数模板中,该模板从迭代器的元素类型中提取类型,以便您可以auto做到。(在 C++11 中,decltype不需要函数也可以,但表达式会很乱。)


zip如果您对and有多种用途map_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++;
}
于 2014-11-03T19:26:38.250 回答
1

IMO,最好的 C++ 替代方法dictstd::unordered_map,它是一个哈希表,而对于zip,它ranges::view::zip来自D4128 范围提案,可以在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++ 标准。

于 2014-11-03T20:12:26.707 回答
0
dict(zip(labels,values))  --->  dict([("a",1),("b",0)]) ---> dict(a=1,b=0)

dict 只是一个哈希表......这只是制作一个标签和值的哈希表,其中标签(或键)wordCollection和标记化字符串是值

所以可能是一个哈希表......虽然在 C++ 中可能需要不止一行来完成它

于 2014-11-03T19:24:44.093 回答