Python-在dict

时间:2018-09-24 15:10:04

标签: python swig

我想问一下在python dict中用作伪值的最便宜的数据类型是什么(就内存消耗和保存/处理而言)(仅dict的键对我很重要,值只是占位符)

例如:

d1 = {1: None, 2: None, 3: None}
d2 = {1: -1, 2: -1, 3: -1}
d3 = {1: False, 2: False, 3: False}

这里只有键(1、2、3)对我有用,它们的值不是,所以它们可以是任何值(仅用作占位符。我想知道的是我应该在此处使用哪些伪数据)。现在,我使用“无”,但不确定是否是“最便宜的”。

P.S。,我知道最好只存储键的选择可能是使用Set而不是dict(带有伪值)。但是,这样做的原因是因为我想使用SWIG在Python和C ++之间交换数据。现在,我已经弄清楚了如何使用SWIG将Python dict以std :: map的形式传递给C ++,但是找不到有关如何将Python Set以std :: set ..的形式传递给C ++的任何信息。

这里非常感谢您的帮助/指导!

2 个答案:

答案 0 :(得分:5)

python 3.4 64位:

>>> import sys
>>> sys.getsizeof(None)
16
>>> sys.getsizeof(False)
24
>>> sys.getsizeof(1)
28
>>> 

所以None似乎是最好的选择(我只列出了不可变的对象,而忽略了字符串和元组)。请注意,因为这些对象通常会被缓存,所以没有多大关系,因此大小不会乘以字典中元素的数量(此外,{em> None被保证为单例) )

也就是说,与为每个键/值对存储对该对象的引用的成本相比,实际对象的成本可以忽略不计。如果您的词典包含1000个值,则无论该值的大小如何,您都可以存储1000个引用。

结论:没关系,只要您在各处都使用相同的引用,并且由于引用,无论如何它都会比集合花费更多的钱被存储为每个字典条目的值。

一种可能的选择是将set作为json表示形式(然后在list中)作为字符指针传递给C ++端,这将使用good json parser。除非您的值是大浮点值(或大整数),否则可以节省内存,因为序列化消除了对象方面。

>>> json.dumps(list(set(range(4,10))))
'[4, 5, 6, 7, 8, 9]'  # hard to beat that in terms of size!

答案 1 :(得分:1)

您可以使用集合,但是SWIG似乎仅支持将Python列表作为set参数传递(或使用命名模板),而无需编写自己的类型映射。示例(Windows):

test.i *

%module test

%include <std_set.i>
%template(seti) std::set<int>;

%inline %{

#include <set>
#include <iostream>
void func(std::set<int> a)
{
    for(auto i : a)
        std::cout << i << std::endl;
}

%}

输出:

>>> import set
>>> s = test.seti([1,1,2,2,3,3])  # pass named template
>>> test.func(s)
1
2
3
>>> test.func([1,2,3,3,4,4])  # pass a list that converts to a set
1
2
3
4
>>> test.func({1,1,2,2,3})   # Actual set doesn't work.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: in method 'func', argument 1 of type 'std::set< int,std::less< int >,std::allocator< int > >'