-6

我有一个很大的清单,像这样:

['a', 'b', 'c', 'd', 'e', 'f', 'g', ...]

我想使用字典来跟踪它的索引。字典看起来像这样:

{1:'a', 2:'b', 3:'c', 4:'d', 5:'e', 6:'f', 7:'g', ...}

但随后我需要插入新元素。我希望插入点之后的列表元素的索引在插入时自动增加 1。有没有一种快速或传统的方法来做到这一点?我通常使用python,但其他形式的算法就可以了。

更新:请不要无缘无故地否决这个问题。我认为即使省略了一些上下文(为简单起见),问题本身也很清楚。我认为可以提供答案,而不必知道我为什么需要这样做。

4

3 回答 3

6

为什么有一个 dict 将索引映射到值?这就是列表已经做的:

>>> x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', ...]
>>> x[0]
'a'
>>> x[4]
'e'

如果您修改列表,例如通过插入新值,则索引会自动正确。

您的 dict 和列表本身之间的唯一区别是列表是 0 索引的,而您的 dict 是 1 索引的('a' 是 1)。

于 2012-06-26T03:32:16.647 回答
0

这是一个封装整数重新编号和基于 1 的索引的类。请参阅最后的示例,了解此类的实例如何模拟 dict 的接口,即使它本身不是 dict。

# define DEFAULT value that is very unlikely to be a list value
DEFAULT=object()

class IndexedList(object):
    def __init__(self, seq=None):
        self._seq = list(seq) if seq is not None else []
    def __contains__(self, key):
        if isinstance(key, int):
            return 1 <= key <= len(self._seq)
        else:
            return key in self._seq
    def __getitem__(self, index):
        return self._seq[index-1]
    def __setitem__(self, index, value):
        self._seq[index-1] = value
    def __str__(self):
        return str(self._seq)
        # or if you'd rather have it look like a dict
        # return "{%s}" % ', '.join("%d: '%s'" % (i,s) for i,s in self.iteritems())
    def iterkeys(self):
        i = 1
        while i <= len(self._seq):
            yield i
            i += 1
    def keys(self):
        return list(self.iterkeys())
    def itervalues(self):
        return iter(self._seq)
    def values(self):
        return list(self.itervalues())
    def iteritems(self):
        return enumerate(self._seq, start=1)
    def items(self):
        return list(self.iteritems())
    def insert(self, i, value):
        self._seq.insert(i-1, value)
    def pop(self, i, default=DEFAULT):
        if i in self:
            return self._seq.pop(i-1)
        else:
            if default is not DEFAULT:
                return default
            else:
                raise KeyError("%s not a valid key" % i)
    # everything else, just delegate to owned list object
    def __getattr__(self, attr):
        return getattr(self._seq, attr)


# make an instance of IndexedList; print items just like it was a dict
il = IndexedList("abcdefg")
print il
print il.items()
# Prints
# ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g')]
#   or if you choose to show dict-ish output
# {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g'}
# [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g')]


# insert an item into the middle of the sequence, note that
# remaining items get incremented keys
il.insert(4,'x')
print il
print il.items()
# Prints
# ['a', 'b', 'c', 'x', 'd', 'e', 'f', 'g']
# [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'x'), (5, 'd'), (6, 'e'), (7, 'f'), (8, 'g')]


# test dict.pop
print il.pop(3)
print il
print il.items()
# Prints
# c
# ['a', 'b', 'x', 'd', 'e', 'f', 'g']
# [(1, 'a'), (2, 'b'), (3, 'x'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g')]


# test 'key in dict' behavior
print 0 in il
print 3 in il
print 100 in il
print il.keys()
print il.values()
# Prints
# False
# True
# False
# [1, 2, 3, 4, 5, 6, 7]
# ['a', 'b', 'x', 'd', 'e', 'f', 'g']


# so you can treat il directly as a dict, but if you really really need a dict
# object, make one using il.iteritems
ildict = dict(il.iteritems())
print ildict
# Prints
# {1: 'a', 2: 'b', 3: 'x', 4: 'd', 5: 'e', 6: 'f', 7: 'g'}
于 2012-06-26T05:17:10.313 回答
0

您声明要使用索引来跟踪到其他列表的映射。这是一个大数据集,所以查找速度可能很重要(字典在这里有很大的优势)。

如果索引不是数据的绝对必要部分——而且只是一种方便的引用关系的方式——那么为什么要将事物存储在单独的列表中呢?您是否考虑过嵌套字典,以便将所有相关数据保存在一起?例如,

dataset = { 'a': { 'name':'Alice' , 'food':'pie' } , 'b': { 'name':'Bob' , 'food':'cake' , 'friend':'Eve' } }

>>> dataset['a']['food']
'pie'

这更具可读性,并且字典为给定的任意数据块提供比大型列表更快的查找。但是,如果不了解您的目标,就很难推荐量身定制的解决方案。例如,了解是否所有数据都可以通过键引用(您总是在寻找“a”)或者您是否有时想要查找特定值(每个喜欢 pie 的人)都会有所帮助。

于 2012-06-26T05:07:50.553 回答