python - 哪个数据结构用作一个数组的字典?
问题描述:
我需要建立一个数据结构,像这样的:python - 哪个数据结构用作一个数组的字典?
{
key: {k: v for k in range(fixed_small_number)}
for key in range(fixed_large_number)
}
事情是我建立它在“香艳”的方式,在每一次得到一个更多的项目放在一个随机k代表一个随机密钥,即我需要随机访问,我需要内部字典是可变的。
所以我的问题分为两个:
推荐的类型外字典。
内部字典的推荐类型。
对我来说,“最佳”解决方案将是一个可变的namedtuples数组,只有这个不存在。
我可以使用namedtuples列表,然后用新数据重新创建每个列表,但这听起来超级浪费,列表不是随机访问高效的,而是所有重写的相同数据。
有没有我不知道的一些神奇的新结构?
编辑:使用的 例如:
for key, k, v in [('a', 1, 2), ('b', 1, 3), ('a', 2, 1), ('a', 3, 1), ('b', 3, 1) ...]:
my_structre[key][k] = v
EDIT2:
事实证明,列表实际上做support random access
答
你可以建立一个自定义类,使用__slots__
限制量可能使用的内存:
class MutableEfficientNamedList(object):
__slots__ = ('field1', 'field2', 'field3')
def __init__(self, *values):
for k, v in zip(self.__slots__, values):
setattr(self, k, v)
def __getitem__(self, i):
return getattr(self, self.__slots__[i])
def __setitem__(self, i, v):
return setattr(self, self.__slots__[i], v)
def __repr__(self):
return '{}({})'.format(type(self).__name__,
', '.join(repr(getattr(self, s)) for s in self.__slots__))
然后在你的结构中使用这些。它们可以像命名元组一样使用(允许通过索引和按名称访问),但它们允许突变。通过使用__slots__
每个实例的内存占用量仍然很低:
>>> menl = MutableEfficientNamedList('foo', 'bar', 'baz')
>>> menl
MutableEfficientNamedList('foo', 'bar', 'baz')
>>> menl.field1
'foo'
>>> menl[0]
'foo'
>>> menl[1]
'bar'
>>> menl[1] = 'spam'
>>> menl.field2
'spam'
当然,你给插槽有意义的名称,并请挑选一个更好的名字为自己的课程比我在我的例子中使用。 :-)
要在namedtuple()
模式扩大,这里是一个通用的工厂函数:
def namedlist(name, *attrs):
"""Create a named list class named `name` with attributes `attrs`.
`attrs` must be strings representing valid Python identifiers.
"""
class MutableEfficientNamedList(object):
__slots__ = attrs
def __init__(self, *values):
for k, v in zip(self.__slots__, values):
setattr(self, k, v)
def __getitem__(self, i):
return getattr(self, self.__slots__[i])
def __setitem__(self, i, v):
return setattr(self, self.__slots__[i], v)
def __repr__(self):
return '{}({})'.format(type(self).__name__,
', '.join(repr(getattr(self, s)) for s in self.__slots__))
MutableEfficientNamedList.__name__ = name
return MutableEfficientNamedList
MyList = namedlist('MyList', 'foo', 'bar', 'baz')
nl = MyList(1, 2, 3)
print nl # MyList(1, 2, 3)
print nl.bar # 2
print nl[1] # 2
答
defaultdict
感觉就在这里:
from collections import defaultdict
d = defaultdict(lambda: defaultdict(int))
d[3][4] = 10
如果你想固定大小的列表,defaultdict
有你涵盖:
d = defaultdict(lambda: [None]*fixed_small_number)
d[3][4] = 10
# d[3] is now [None, None, None, None, 10, None, None, ...]
答
鉴于你r示例:
for key, k, v in [('a', 1, 2), ('b', 1, 3), ('a', 2, 1), ('a', 3, 1), ('b', 3, 1) ...]:
my_structre[key][k] = v
该解决方案确实是通过使用defaultdict
。
from collections import defaultdict
d = defaultdict(dict)
for key, k, v in [('a', 1, 2), ('b', 1, 3), ('a', 2, 1), ('a', 3, 1), ('b', 3, 1)]:
d[key][k] = v
答:
{'a': {1: 2, 2: 1, 3: 1}, 'b': {1: 3, 3: 1}}
作为一个功能:
def method(iter_of_3_item_iters):
d = defaultdict(dict)
for (a, b, c) in iter_of_3_item_iters:
d[a][b] = c
return d
我不知道这是可能的,如果我理解正确的问题。像dict这样的可变对象不能是字典键。 – millimoose 2013-03-10 13:29:25
无论如何,目前还不清楚你想要完成什么。你能举一个例子说明这个数据结构是如何“折衷地”构建的?即给定单个更新之前和之后的状态? – millimoose 2013-03-10 13:30:44
我不知道我明白..我在哪里建议,字典将作为密钥? – phistakis 2013-03-10 13:31:46