【问题标题】:Python list set value at index if index does not exist如果索引不存在,Python 列表在索引处设置值
【发布时间】:2014-04-18 19:00:24
【问题描述】:

python 中有没有一种方法、lib 或其他东西可以在不存在的索引处设置列表中的值? 类似于在列表中创建运行时索引:

l = []
l[3] = 'foo'
# [None, None, None, 'foo']

更进一步,使用多维列表:

l = []
l[0][2] = 'bar'
# [[None, None, 'bar']]

或者使用现有的:

l = [['xx']]
l[0][1] = 'yy'
# [['xx', 'yy']]

【问题讨论】:

  • 如果你正在寻找类似自动生存的东西,def tree(): return defaultdict(tree) 会给你一个字典,当你请求一个不存在的条目时,它会递归地生成新的字典。
  • 你有什么理由不能只使用字典吗?我看到的唯一区别是较低的索引被初始化为 None。

标签: python python-3.x multidimensional-array


【解决方案1】:

并非万无一失,但似乎最简单的方法是初始化一个比您需要的大得多的列表,即

l = [None for i in some_large_number]
l[3] = 'foo'
# [None, None, None, 'foo', None, None None ... ]

【讨论】:

    【解决方案2】:

    如果您真的想要问题中的语法,defaultdict 可能是获得它的最佳方式:

    from collections import defaultdict
    def rec_dd(): 
        return defaultdict(rec_dd)
    
    l = rec_dd()
    l[3] = 'foo'
    
    print l
    {3: 'foo'}
    
    l = rec_dd()
    l[0][2] = 'xx'
    l[1][0] = 'yy'
    print l
    <long output because of defaultdict, but essentially)
    {0: {2: 'xx'}, 1: {0: 'yy'}}
    

    它并不完全是一个“列表列表”,但它或多或少有点像。

    您确实需要指定用例...上面有一些优点(您可以访问索引而无需先检查它们是否存在),也有一些缺点 - 例如,l[2] 在普通字典中将返回KeyError,但在 defaultdict 中它只是创建一个空白 defaultdict,添加它,然后返回它。

    支持不同语法糖的其他可能实现可能涉及自定义类等,并且会有其他权衡。

    【讨论】:

    • 这很好,但我需要一个数组。您能展示如何将其转化为一体吗?
    • 如果你需要一个数组...你应该使用一个数组。但是,您可以在填充 for index in range(10): do_something(l[index]) 后执行类似的操作 - 即,即使它看起来 不像数组,但对于大多数用途而言,它行为 像数组。如果l[i] 不存在,您将需要定义它的含义 - 这将创建一个空的defaultdict 对象,但如果您看到它,您的算法中可能已经存在一些错误。
    【解决方案3】:

    没有内置,但很容易实现:

    class FillList(list):
        def __setitem__(self, index, value):
            try:
                super().__setitem__(index, value)
            except IndexError:
                for _ in range(index-len(self)+1):
                    self.append(None)
                super().__setitem__(index, value)
    

    或者,如果您需要更改现有的原版列表:

    def set_list(l, i, v):
          try:
              l[i] = v
          except IndexError:
              for _ in range(i-len(l)+1):
                  l.append(None)
              l[i] = v
    

    【讨论】:

    • 多维是困难的......假设你做了一些你想让l[i]成为None的事情,如果它不存在-然后l[3] = 'three'创建[None, None, None, 'three']。但是假设您然后执行l[0][3] - 当对l[0] 的查找完成时,代码不知道您想再次取消引用它,因此它不知道将None 更改为@987654330 @,它失败了。任何多维解决方案都存在无法读心的问题......
    【解决方案4】:

    您不能创建有间隙的列表。您可以使用dict 或这个快速的小家伙:

    def set_list(i,v):
        l = []
        x = 0
        while x < i:
            l.append(None)
            x += 1
        l.append(v)
        return l
    
    print set_list(3, 'foo')
    >>> [None, None, None, 'foo']
    

    【讨论】:

    • 但是如果我想添加到现有列表中呢?比如: set_list(['a', 'b'], 3, 'foo') # ['a', 'b', None, 'foo']
    猜你喜欢
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多