使用Python列表
L=[1,2,3,4]
如果L[m] = 0
与m
不同,我希望0,1,2,3
,即:
...
L[-2]=0
L[-1]=0
L[0]=1
L[1]=2
L[2]=3
L[3]=4
L[4]=0
L[5]=0
和
L[-2:2] = [0, 0, 1, 2]
这不适用于经典列表或数组。这样做的好方法是什么?
编辑:这是一个很好的解决方案(由一个答案给出):
class MyList(list):
def __getitem__(self, index):
return super(MyList, self).__getitem__(index) if index >= 0 and index < len(self) else 0
但我仍然无法拥有
L[-2:2] = [0, 0, 1, 2]
答案 0 :(得分:6)
您可以将L
转换为dict:
In [1]: L=[1,2,3,4]
In [2]: D=dict([(x, y) for x, y in enumerate(L)])
In [3]: [D.get(i, 0) for i in xrange(-3, 5)]
Out[3]: [0, 0, 0, 1, 2, 3, 4, 0]
答案 1 :(得分:1)
解决问题之一是声明你自己的get函数
def get(l, p):
try:
return l[p]
except IndexError:
return 0
ofc最后一行可以是l.append(0)或其他
答案 2 :(得分:1)
您可以使用特殊的get函数:
def get(l, p):
return l[p] if p >= 0 and p < len(l) else 0
甚至覆盖__getitem__
方法:
class MyList(list):
def __getitem__(self, index):
return super(MyList, self).__getitem__(index) if index >= 0 and index < len(self) else 0
示例:
>>> l2 = MyList([3, 5, 6, 8])
>>> l2[-1]
0
>>> l2[5]
0
>>> l2[2]
6
答案 3 :(得分:1)
您可以将内置列表子类化为在访问列表项时提供默认值:
class MyList(list):
def __getitem__(self, item):
if isinstance(item, slice):
step = item.step if item.step else 1
return [self.__getitem__(i) for i in xrange(item.start, item.stop, step)]
try:
value = super(MyList, self).__getitem__(item)
except IndexError:
value = 0
return value
def __getslice__(self, start, stop):
return self.__getitem__(slice(start, stop, None))
使用示例:
>> L = MyList([1,2,3,4])
>> L[0]
1
>> L[1]
2
>> L[2]
3
>> L[3]
4
>> L[4]
0
>> L[5]
0
>> L[0:6]
[1, 2, 3, 4, 0, 0]
信用转到How to override the slice functionality of list in its derived class
答案 4 :(得分:1)
您可以使用slice
个对象,这些对象在使用“扩展切片”时不会传递给__getslice__
,而是传递给__getitem__
。然后,将切片的start
移至0
,将stop
移至len - 1
,同时保持跟踪。然后添加零:
class MyList(list):
def __getitem__(self, item):
if isinstance(item, slice):
s, e = item.start, item.stop
l = len(self) - 1
left = -s if s < 0 else 0
s = max(s, 0)
right = e - l if e > l else 0
e = min(e, l)
return [0]*left + super(MyList, self).__getitem__(slice(s,e,item.step)) + [0]*right
elif item < 0 or item >= len(self):
return 0
else:
return super(MyList, self).__getitem__(item)
问题是:您必须强制getslice
调用以发送slice
对象,您可以通过以下两种方式之一来执行此操作。
>>> a[-2:2:1] # the step = 1 is necessary
[0, 0, 1, 2]
或
>>> a[slice(-2,2)]
[0, 0, 1, 2]
两端都有效:
>>> a[-2:6:1]
[0, 0, 1, 2, 3, 0, 0, 0]
如果__getslice__
传递了a[-2:2]
给出的实际参数,那么这将有效:
class MyList(list):
def __getitem__(self, item):
if item < 0 or item >= len(self):
return 0
return super(MyList, self).__getitem__(item)
def __getslice__(self, s, e):
print "input: ", s, e
l = len(self) - 1
left = -s if s < 0 else 0
s = max(s, 0)
right = e - l if e > l else 0
e = min(e, l)
return [0]*left + super(MyList, self).__getslice__(s,e) + [0]*right
但由于某些原因,a[-2:2]
调用a.__getslice(2,2)
并且两个值均为正值。
>>> a[-2:2]
input: 2 2
答案 5 :(得分:0)
列表中的随机索引len仅适用于切片。如果要获取(或设置)某些对象,则必须仅在列表范围内使用索引。 所以
L[4]=0
x=L[4]
不起作用,但
L[4:6]=0,0 or L[4:6]=[0,0]
x,y=L[2:10000] # x=3,y=4
将起作用