0

在 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
4

3 回答 3

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 功能集成可能会很棘手(负索引、切片)。

于 2013-04-06T01:04:47.167 回答
2

zch 已经给出了一个很好的答案,但我会发布这个来告诉你如何复制get的行为

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)
于 2013-04-06T01:25:19.723 回答
1

我想不出这种实现方式的原生方式。话虽如此,创建一个符合您期望的函数并不是一个坏主意。而不是 using 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使用。这在特定情况下经过了少量测试和工作,但不能保证完美:)

于 2013-04-06T00:59:08.097 回答