在Python中,是否可以模仿JavaScript数组(即,在数组范围之外添加值时自动扩展的数组)?在JavaScript中,当在数组的索引之外分配值时,数组会自动扩展,但在Python中,它们不会:
theArray = [None] * 5
theArray[0] = 0
print(theArray)
theArray[6] = 0 '''This line is invalid. Python arrays don't expand automatically, unlike JavaScript arrays.'''
这在JavaScript中是有效的,我试图在Python中模仿它:
var theArray = new Array();
theArray[0] = 0;
console.log(theArray);
theArray[6] = 0; //the array expands automatically in JavaScript, but not in Python
答案 0 :(得分:4)
如果你真的需要,你可以定义这样的结构:
class ExpandingList(list):
def __setitem__(self, key, value):
try:
list.__setitem__(self, key, value)
except IndexError:
self.extend((key - len(self)) * [None] + [value])
>>> a = ExpandingList()
>>> a[1] = 4
>>> a
[None, 4]
>>> a[4] = 4
>>> a
[None, 4, None, None, 4]
将它与其他python功能集成可能很棘手(负索引,切片)。
答案 1 :(得分:2)
zch has already given a great answer,但我会发布此信息,向您展示如何复制获取的行为
class MyList(list):
@property
def length(self): # for the example bracket notation
return len(self)
def __getitem__(self, key): # Fix GET
try: # assume permission
return list.__getitem__(self, key)
except (IndexError, TypeError): # "ask forgiveness"
pass # using pass to save indents as try was a return
if key == 'length': # example bracket notation for length getter
return self.length
try: # JavaScript doesn't care about number type and accepts
key = int(key) # strings, too, but Python req.s integers
return list.__getitem__(self, int(key))
except (IndexError, ValueError):
pass
return None
def __setitem__(self, key, value): # Fix SET
try:
list.__setitem__(self, key, value)
return value # copy return behaviour
except (IndexError, TypeError):
pass
try:
key = int(key) # force int
except ValueError:
return # fail quietly?
if key < 0: # still throw for bad key
raise IndexError()
self.extend((key - len(self)) * [None]) # fill gap with None
self.append(value) # append new value
return value # copy return behaviour
>>> a = MyList()
>>> a[0] = 1
>>> a[2] = 1
>>> (a, a[3])
([1, None, 1], None)
>>> (a.length, a['length'])
(3, 3)
答案 2 :(得分:1)
我想不出这是实现的本地方式。说到这一点,创建一个能达到预期效果的功能并不是一个坏主意。您可以使用以下内容代替使用my_list[index] = value
:
def insertWithAutoFill(the_list, index, new_item):
if index >= len(the_list):
for i in range(len(the_list), index):
the_list.append(None)
the_list.append(new_item)
else:
the_list[index] = new_item
你会这样称呼:
my_list = [1, 2, 3]
insertWithAutoFill(my_list, 6, 23)
现在my_list
包含:
[1, 2, 3, None, None, None, 23]
您可能需要调整一些内容以确保正确检查某些内容并正确使用index
。这是在特定情况下进行了轻微测试和工作,但并不能保证完美:)