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