Python:我有一个双键列表,这是retrei最有效的存储对象

2024-03-29 05:17:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用的是两个层次结构的数据集,它们包含一个复杂的关系(我没有使用SQL),它们不共享它们的主要查找键。我们使用这个过程来保持两个数据集的同步。在

每个数据集当前存储为一个字典,数据集的键作为字典的键。在确定了复杂关系之后,我将另一个数据集的键作为另一个数据集的属性存储在另一个数据集中。这就需要创建一些奇怪的helper函数来遵循一些父子关系。在

我想知道是否有一种更有效或更快的方法来处理这种疯狂行为,因为我目前必须将这两个数据集传递给需要解析关系的处理函数。在

示例:

leftdataset = {'10000': { 'key': '10000', 'fkey':'asdf', 'parent':'10001'},
               '10001': { 'key': '10001', 'fkey':'qwer', 'parent':''},}
rightdataset= {'asdf': { 'key': 'asdf', 'fkey':'10000', 'parent':'qwer'},
               'qwer': { 'key': 'qwer', 'fkey':'10001', 'parent':''},

为了找到父对象的fkey,我需要:

^{pr2}$

我在考虑如何呈现一个密钥对的元组,然后在其中寻找我需要的密钥,例如:

keys = [('10000', 'asdf'), ('10001', 'qwer')]

def find_key(key, keyset):
  for keypair in keys:
    if key in keypair:
      k1, k2 = keypair
      if k1 == key:
        return k2
      else:
        return k1

但这听起来比我现在做的更没有效率。我是不是走错了路?在


Tags: 数据keyinif字典关系密钥k2
2条回答

这种用法对你有吸引力吗?在

轻松查找和使用单个条目:

>>> left("10000")
Entry({'parent': '10001', 'key': '10000', 'fkey': 'asdf'})
>>> left("10000")['key']
'10000'
>>> left("10000")['parent']
'10001'

方便查找家长:

^{pr2}$

轻松查找相关条目:

>>> left("10001").related()
Entry({'parent': '', 'key': 'qwer', 'fkey': '10001'})
>>> right("qwer")
Entry({'parent': '', 'key': 'qwer', 'fkey': '10001'})
>>> right(left("10001").related()['key'])
Entry({'parent': '', 'key': 'qwer', 'fkey': '10001'})
>>> right("qwer") is left("10001").related()
True

特别是在您的问题中有一个例子:父项的外键:

>>> left("10000").parent()['fkey']
'qwer'

如果是这样的话,这就是密码!课程:

class Entry(object):
    def __init__(self, dataset, d):
        self.dataset = dataset
        self.d = d

    def parent(self):
        return self.dataset.parent_of(self)
    def related(self):
        if not self.dataset.related_dataset:
            raise ValueError("no related dataset specified")
        return self.dataset.related_dataset(self['fkey'])

    def __getitem__(self, k):
        return self.d.__getitem__(k)

    def __repr__(self):
        return "Entry(%s)" % repr(self.d)
    def __str__(self):
        return str(self.d)

class Dataset(object):
    def __init__(self, data):
        self.data = dict((k, Entry(self, v)) for (k,v) in data.items())
        self.related_dataset = None

    def set_related_dataset(self, dataset):
        self.related_dataset = dataset

    def entry(self, key):
        if isinstance(key, Entry): return key
        return self.data[key]
    def __call__(self, key):
        return self.entry(key)

    def parent_of(self, entry):
        entry = self.entry(entry)

        if not entry['parent']:
            return None
        return self.data[entry['parent']]

以及您提供的数据的用途:

leftdata = {'10000': { 'key': '10000', 'fkey':'asdf', 'parent':'10001'},
               '10001': { 'key': '10001', 'fkey':'qwer', 'parent':''},}
rightdata = {'asdf': { 'key': 'asdf', 'fkey':'10000', 'parent':'qwer'},
               'qwer': { 'key': 'qwer', 'fkey':'10001', 'parent':''}}

left = Dataset(leftdata)
right = Dataset(rightdata)
left.set_related_dataset(right)
right.set_related_dataset(left)

说明:将每个dict值包装在一个Entry类中,并定义__getitem__,使其可用作dict(或多或少)。拥有一个将主键映射到这些EntryDataset类。提供对此数据集的Entry访问,并提供方便的方法.parent()和{}。为了使.related()工作,设置“相关”的数据集应该与set_related_dataset在一起,并将其连接在一起。在

现在,您甚至可以只传递Entrys,这样就可以访问相关条目,而不需要同时传入两个数据集。在

根据Mark Ransom的评论,也许你可以组织一个这样的课堂:

class Storage(object):

    def __init__(self):

        self._leftdataset = {
            '10000': { 'key': '10000', 'fkey':'asdf', 'parent':'10001'},
            '10001': { 'key': '10001', 'fkey':'qwer', 'parent':''}
        }

        self._rightdataset= {
            'asdf': { 'key': 'asdf', 'fkey':'10000', 'parent':'qwer'},
            'qwer': { 'key': 'qwer', 'fkey':'10001', 'parent':''}
        }

    def get(self, key):
        d1 = self._leftdataset
        d2 = self._rightdataset

        if key in d1:
            left = d1[key]
            right = d2[left['fkey']]
        else:
            right = d2[key]
            left = d1[right['fkey']]

        return left, right

并使用单个查找方法:

^{pr2}$

相关问题 更多 >