我有一个大清单,如下:
['a', 'b', 'c', 'd', 'e', 'f', 'g', ...]
我想用字典来跟踪它的索引。 dict看起来像这样:
{1:'a', 2:'b', 3:'c', 4:'d', 5:'e', 6:'f', 7:'g', ...}
但是我需要插入新元素。我希望插入点后列表元素的索引在插入时自动增加1。有快速或传统的方法吗?我通常使用python,但其他形式的算法也没问题。
更新:请不要无缘无故地拒绝这个问题。我认为即使省略了一些上下文(为简单起见),问题本身也相当清楚。我认为可以提供答案,而不必知道为什么我需要这样做。
答案 0 :(得分:6)
为什么将dict映射到值?这就是列表已经做的事情:
>>> x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', ...]
>>> x[0]
'a'
>>> x[4]
'e'
如果修改列表,例如通过插入新值,索引会自动正确。
你的dict和列表本身之间的唯一区别是列表是0索引的,你的dict是1索引的('a'是1)。
答案 1 :(得分:0)
您声明要使用索引来跟踪到其他列表的映射。这是一个很大的数据集,所以大概查找速度很重要(字典在这里有很大的优势)。
如果索引不是数据的绝对必要部分 - 并且只是引用关系的便捷方式 - 那么为什么要将东西存储在单独的列表中?您是否考虑过嵌套字典,以便将所有相关数据保存在一起?例如,
dataset = { 'a': { 'name':'Alice' , 'food':'pie' } , 'b': { 'name':'Bob' , 'food':'cake' , 'friend':'Eve' } }
>>> dataset['a']['food']
'pie'
这更具可读性,并且字典为给定的任意数据对大型列表提供了更快的查找速度。但是,如果不了解您的目标,很难推荐量身定制的解决方案。例如,知道是否可以通过键引用所有数据(您总是在寻找'a'),或者您是否有时想要找到特定值(每个喜欢派的人)都会有所帮助。
答案 2 :(得分:0)
这是一个封装整数重编号和基于1的索引的类。最后看一下这个类的实例如何模拟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'}