将python字典翻译成C++
Posted
技术标签:
【中文标题】将python字典翻译成C++【英文标题】:Translating python dictionary to C++ 【发布时间】:2010-12-23 00:16:47 【问题描述】:我有包含以下代码的 python 代码。
d =
d[(0,0)] = 0
d[(1,2)] = 1
d[(2,1)] = 2
d[(2,3)] = 3
d[(3,2)] = 4
for (i,j) in d:
print d[(i,j)], d[(j,i)]
不幸的是,循环遍历 python 中的所有键对于我的目的来说还不够快,我想将此代码转换为 C++。用于以元组为键的 python 字典的最佳 C++ 数据结构是什么?上述代码的 C++ 等价物是什么?
我查看了 boost 库中的稀疏矩阵,但找不到一种仅循环非零元素的简单方法。
【问题讨论】:
您是否考虑过另一种数据布局。如果 (i,j) 总是与 (j,i) 配对,那么您可能并不真的需要两者。您可以在构建字典时建立关联。您可以在入口存储( d(i,j), d(j,i) )中存储 (i,j) 的字典。这假设元组中的数字可以任意排序,这可能是正确的。 另外,如果您只是遍历元组,请将它们存储在一个列表中并遍历该列表。 【参考方案1】:类型是
std::map< std::pair<int,int>, int>
向地图添加条目的代码如下:
typedef std::map< std::pair<int,int>, int> container;
container m;
m[ make_pair(1,2) ] = 3; //...
for(container::iterator i = m.begin(); i != m.end(); ++i)
std::cout << i.second << ' ';
// not really sure how to translate [i,j] [j,i] idiom here easily
【讨论】:
当类型不是从属名称时,您不能使用typename
。
@Roger:你说得对,修复了“typename container::iterator”【参考方案2】:
字典是 c++ 中的 std::map,而具有两个元素的元组是 std::pair。
提供的 python 代码将转换为:
#include <iostream>
#include <map>
typedef std::map<std::pair<int, int>, int> Dict;
typedef Dict::const_iterator It;
int main()
Dict d;
d[std::make_pair(0, 0)] = 0;
d[std::make_pair(1, 2)] = 1;
d[std::make_pair(2, 1)] = 2;
d[std::make_pair(2, 3)] = 3;
d[std::make_pair(3, 2)] = 4;
for (It it(d.begin()); it != d.end(); ++it)
int i(it->first.first);
int j(it->first.second);
std::cout <<it->second <<' '
<<d[std::make_pair(j, i)] <<'\n';
【讨论】:
确实很好。好工作。对于像我这样致力于将他们的技能从老式 C++ 升级到现代 C++ 的人来说非常有指导意义。d[*it]
应该是it->second
看来这个错误是joshperry
编辑引入的
请注意,在 C++14 中,std::make_pair(a, b)
可以通过简单地编写 a, b
来替换,这样看起来更干净。【参考方案3】:
看看Boost.python。它用于 python 和 C++ 之间的交互(基本上是使用 C++ 构建 python 库,但也用于将 python 嵌入到 C++ 程序中)。描述了大多数 python 数据结构及其 C++ 等效项(没有检查您想要的那个)。
【讨论】:
【参考方案4】:std::map
或更可能是std::tr1::unordered_map
/ boost::unordered_map
(又名hash_map
)是您想要的。
另外,正如 kriss 所说,Boost.Python 是一个不错的主意。它已经提供了 python 的 dict 类的 C++ 版本,所以如果你正在做跨语言的东西,它可能会很有用。
【讨论】:
【参考方案5】:作为您问题的直接答案(对于 python 部分,请查看我的其他答案)。如果你愿意,你可以忘记元组部分。您可以在 C++ 中使用任何映射类型的键/值(哈希等),您只需要找到一个唯一的键函数即可。在某些情况下,这很容易。例如,如果您的两个整数是 1 到 65536 之间的整数,您只需使用一个 32 位整数,每个 16 位都是键之一。一个简单的移位和一个“或”或+来组合这两个值就可以了,而且非常有效。
【讨论】:
【参考方案6】:您想通过 Python 调用优化的 C++ 例程吗?如果是这样,请继续阅读:
在 Python 中处理字典时,我经常使用PyYaml。也许您可以将LibYAML 或yamlcpp 之类的链接链接到:
-
将 Python 字典翻译成 YAML 字符串
使用 Python 调用使用 SWIG 之类的东西封装的 C++ 函数,将 YAML 字符串作为参数。
使用 C++ 库解析 YAML 并获取
std::map
对象
在 std::map 对象上操作
警告:我从未尝试过,但在"yaml std::map" 上使用大家最喜欢的搜索引擎会产生很多有趣的链接
【讨论】:
【参考方案7】:Map 通常被实现为平衡二叉树而不是哈希表。这不是 Python 字典的情况。所以你需要一个 C++ O(1) 等效的数据结构来使用你的对。
【讨论】:
以上是关于将python字典翻译成C++的主要内容,如果未能解决你的问题,请参考以下文章