【问题标题】:Translating python dictionary to C++将python字典翻译成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) 的字典。这假设元组中的数字可以任意排序,这可能是正确的。
  • 另外,如果您只是遍历元组,请将它们存储在一个列表中并遍历该列表。

标签: c++ python dictionary tuples


【解决方案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-&gt;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。也许您可以将LibYAMLyamlcpp 之类的链接链接到:

        1. 将 Python 字典翻译成 YAML 字符串
        2. 使用 Python 调用使用 SWIG 之类的东西封装的 C++ 函数,将 YAML 字符串作为参数。
        3. 使用 C++ 库解析 YAML 并获取 std::map 对象
        4. 在 std::map 对象上操作

        警告:我从未尝试过,但在"yaml std::map" 上使用大家最喜欢的搜索引擎会产生很多有趣的链接

        【讨论】:

          【解决方案7】:

          Map 通常被实现为平衡二叉树而不是哈希表。这不是 Python 字典的情况。所以你需要一个 C++ O(1) 等效的数据结构来使用你的对。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-07
            • 2017-10-12
            相关资源
            最近更新 更多