【问题标题】:how to keep track of list indices when inserting new elements?插入新元素时如何跟踪列表索引?
【发布时间】:2012-06-27 08:41:49
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 在 C#.NET 中有一个 Dictionary 集合可以完全满足您的需求,我假设 python 会有类似的东西 tutorialspoint.com/python/python_dictionary.htm
  • 你用什么语言工作?
  • dict(enumerate(yourlist)) 离你想去的地方有多近?
  • 你真正想做什么?为什么要这样“跟踪它的索引”?
  • 提供一些上下文是一个非常非常好的主意,原因有两个:1. 它允许人们创建准确地做你想要的测试用例,以及 2. 有时,人们提出的问题不是最好的做事方式。例如,有人可能会建议您不知道的更好的数据结构或 python 模块。

标签: python list insert indexing


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      这是一个封装整数重新编号和基于 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'}
      

      【讨论】:

        猜你喜欢
        • 2013-05-26
        • 2018-02-08
        • 1970-01-01
        • 2012-03-05
        • 1970-01-01
        • 2014-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多