动态增长Python数组的方法是什么?

13

我希望能在Python中填充一个数组,以便我可以使用id号来索引数组。并非所有索引都存在于数组中,而且项目不一定按顺序添加到数组中。最大可能的索引未知(或者至少我不想硬编码它)。在分配时是否有一种动态增长数组的方法?

arr = []
for x in xs
    arr[x.index] = x

但是这会产生"IndexError: list assignment index out of range"错误。我尝试使用list.insert(),但如果不按顺序插入项,则无法工作,因为它会更改数组中已有项的索引。

在Python中是否有好的方法来解决这个问题,或者我必须接受初始化足够大的数组的事实?


你所称之为 Python 的 array 实际上是一个 list - Junuxx
请参考更好的答案:https://dev59.com/KW855IYBdhLWcg3wFALy - David Sharnoff
请参考以下链接获得更好的答案:https://dev59.com/KW855IYBdhLWcg3wFALy - David Sharnoff
4个回答

12

你需要一个字典

arr = {}
for x in xs:
    arr[x.index] = x

如果你只是想要构建一个字典,可以使用字典推导式,示例如下:

myDict = {x.index:x for x in xs}

2
tengfred:如果数据集稀疏且大小未知,使用字典可能会很好。但是与数组(或列表)不同,它的内容是无序的,这意味着无法按顺序迭代它们——但如果您仅通过x.index访问它们,则可能并不重要。 - martineau
一个字典似乎可以解决问题,尽管我的数据集非常密集。另一方面,性能并不关键,所以这可能已经足够好了。 - tengfred
@martineau,总是可以使用OrderedDict来保留原始数据集和派生字典之间的顺序。在这种情况下,您需要更改声明为:from collections import OrderedDict; arr = OrderedDict()。但是,您不能使用列表推导式来构建OrderedDict。 - Keith Hanlan
1
实际上,字典在Python 3.6中开始非官方地维护顺序,在3.7+版本中正式维护顺序,这可能使得观点无关紧要。此外,可以使用列表推导式创建一个OrderedDict——事实上,这是推荐的方式(或者至少曾经是)。 - martineau
感谢@martineau提供的信息。不用导入OrderedDict会很好。我期待着能够迁移到3.7(特别是对于f-strings)。而且,我的列表压缩理解有误:在我的实验中,我没有使用正确的语法。感谢您的纠正。 - Keith Hanlan

8

Python 数组可以动态增长,但是简单地为一个索引赋值并不能扩展数组。

数组有 extend 方法,可以从集合中一次性添加多个项。例如:

>>> a = [1, 2, 3]
>>> a.extend([None, None])
>>> a
[1, 2, 3, None, None]

您可以这样模拟自动扩展数组赋值:
def arr_assign(arr, key, val):
    try:
        arr[key] = val
        return
    except IndexError:
        # Do not extend the array for negative indices
        # That is ridiculously counterintuitive
        assert key >= 0
        arr.extend(((key + 1) - len(arr)) * [None])
        arr[key] = val
        return

例如:

>>> a = []
>>> arr_assign(a, 4, 5)
>>> a
[None, None, None, None, 5]

作为附录,那些默认具备自动扩展行为的语言(例如Perl、Ruby、PHP、JavaScript和Lua)往往比Python更加宽松,如果您访问数组中不存在的槽位,则它们会返回一个神奇的空值。这意味着它们可以允许在分配给不存在的索引时进行自动扩展,而不会改变任何其他索引处数组的行为。
例如,在Ruby中,尽管a已经在其下发生了变化,但a[2]并没有改变。
irb(main):006:0> a = []
=> []
irb(main):007:0> a[2]
=> nil
irb(main):008:0> a[4] = 7
=> 7
irb(main):009:0> a
=> [nil, nil, nil, nil, 7]
irb(main):010:0> a[2]
=> nil

0
x = []
ch=int(input("How many values you want to add in an array"))
for i in range(ch):
    z=int(input("Enter value for array"))
    x.append(z) #now u r pushing value of Z entered by you at run time
print(x)

1
问题不在于简单地插入值,而是包含索引和值的结构体。 - banan3'14

-1

为什么不尝试在列表中添加元素呢?

arr = []
for x in xs
    arr.append(x)

然后访问 arr 的方式是:arr[0]、arr[1] 等等。

你好!我认为你在这个帖子上得到负分的原因(不是我给的)是因为答案没有遵循问题的要求。请查看Faust的答案以了解更多关于正确格式的信息。我喜欢你解决问题的方法,请调整你的答案并在准备好后取消删除。祝你好运! - karlphillip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接