代码之家  ›  专栏  ›  技术社区  ›  Cheok Yan Cheng

如何同时具有元组和字典特性的数据结构

  •  2
  • Cheok Yan Cheng  · 技术社区  · 14 年前

    通过引用代码

    http://initd.org/psycopg/docs/extras.html#dictionary-like-cursor

    >>> rec['data']
    "abc'def"
    >>> rec[2]
    "abc'def"
    

    6 回复  |  直到 14 年前
        1
  •  5
  •   Katriel    14 年前

    在Python中 [] 查找由 __getitem__ magic方法;换句话说,当为自定义类编制索引时,Python将调用 instance.__getitem__(...) 把价值还给你。你可以这样做。

    >>> class Foo:
    ...     def __getitem__(self, value):
    ...             return value
    ...
    >>> foo = Foo()
    >>> foo["1"]
    '1'
    >>> foo[0]
    0
    

    二者都 一个dict和一个列表,并根据键的类型索引到其中一个。

    0 作为一把钥匙。也许值得写一个不同的方法,例如。 index 处理索引。

    您也可以执行 __setitem__ __contains__ 方法。

        2
  •  2
  •   Community CDub    7 年前

    这是修改版的 demas

    class TupleDict(collections.OrderedDict):
    
        def __getitem__(self, key):
           if isinstance(key, int):
               return list(self.values())[key]
           return super(TupleDict, self).__getitem__(key)
    
        3
  •  1
  •   pyfunc    14 年前

    读代码。这是我最好的建议。

    例如:

    class cursor(_2cursor):
        """psycopg 1.1.x cursor.
    
        Note that this cursor implements the exact procedure used by psycopg 1 to
        build dictionaries out of result rows. The DictCursor in the
        psycopg.extras modules implements a much better and faster algorithm.
        """
    
        def __build_dict(self, row):
            res = {}
            for i in range(len(self.description)):
                res[self.description[i][0]] = row[i]
            return res
        .....
    

    从哪里来的。。

    class connection(_2connection):
        """psycopg 1.1.x connection."""
    
        def cursor(self):
            """cursor() -> new psycopg 1.1.x compatible cursor object"""
            return _2connection.cursor(self, cursor_factory=cursor)
    
        4
  •  1
  •   aaronasterling    14 年前

    在阅读了格伦·梅纳德关于导致我删除这个答案的评论之后,我决定重新恢复它。它使用一个普通的列表来存储索引,因此具有相同的O(1)访问权限。


    这是我的看法。错误处理可能会得到改进,但我不想把代码弄得太乱。我不知道原始代码是如何处理的,但为什么不继续处理切片呢。我们只能处理不创建新键(即,不更改项计数)的切片的切片分配,但我们可以处理任意切片查找。请注意,它还有效地禁止整数键。这是一个 small demo 在行动中。

    class IndexedDict(object):
        def __init__(self, *args, **kwargs):
            d = dict(*args, **kwargs)
            self._keys = d.keys() # list(d.keys()) in python 3.1
            self._d = d
    
        def __getitem__(self, item):
            if isinstance(item, int):
                key = self._keys[item]
                return self._d[key]
            elif isinstance(item, slice):
                keys = self._keys[item]
                return tuple(self._d[key] for key in keys)
            else:
                return self._d[key]
    
        def __setitem__(self, item, value):
            if isinstance(item, int):
                key = self._keys[item]
                self._d[key] = value
            elif isinstance(item, slice):
                # we only handle slices that don't require the creation of
                # new keys.
                keys = self._keys[item]
                if not len(keys) == len(value):
                    raise ValueError("Complain here")
                for key, v in zip(keys, value):
                    self._d[key] = v
            else:
                self._d[item] = value
                if item not in self._keys:
                    # This is the only form that can create a new element
                    self._keys.append(item)
    
    
        def __delitem__(self, item):
            if isinstance(item, int):
                key = self._keys[item]
                del self._keys[item]
                del self._d[key]
            elif isinstance(item, slice):
                keys = self._keys[item]
                del self._keys[item]
                for key in keys:
                    del self._d[key]
            else:
                del self._d[item]
                self._keys.remove(item)
    
        def __contains__(self, item):
            if isinstance(item, int):
                return i < len(self._keys)
            else:
                return i in self._d
    
        # Just for debugging. Not intended as part of API.
        def assertions(self):
            assert len(self._d) == len(self._keys)
            assert set(self._d.keys()) == set(self._keys)
    

    还有一些事情要做。 keys , items , iteritems update 等等,但不应该太难。只是和 self._keys 并使用列表组件和生成器表达式。例如, iteritems公司 只是 (self._d[key] for key in self._keys) self.\u键 self._keys += [key for key in other.keys() if key not in self._keys] . 我甚至可以定义 __add__ 基本上是一样的。

        5
  •  0
  •   dan_waterworth    14 年前

    字典可以将任何python类型映射到任何其他python类型,因此检索键为整数的值很简单。

    v = {}
    v[0] = 'a'
    v[1] = 'b'
    v['abc'] = 'def'
    
    >>> v[0]
    'a'
    
        6
  •  0
  •   ceth    14 年前

    class d(dict):
        def __getitem__(self, key):
           if str(key).isdigit():
               return self.values()[key]
           else:
               return super(d, self).get(key)
    
    cls = d()
    cls["one"] = 1
    print cls["one"]
    print cls[0]