【问题标题】:Populate a list in python在python中填充列表
【发布时间】:2010-10-16 08:41:05
【问题描述】:

我有一系列代表坐标的 Python 元组:

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]

我想创建以下列表:

l = []
for t in tuples:
  l[ t[0] ][ t[1] ] = something

我得到一个 IndexError: list index out of range.

我的背景是 PHP,我希望在 Python 中您可以创建以索引 > 0 开头的列表,即创建空白然后填充它们,但似乎您不能。

我们的想法是在之后对列表进行排序。我知道我可以用字典来做到这一点,但据我所知,字典不能按键排序。 更新:我现在知道他们可以 - 查看已接受的解决方案。

编辑: 我想要做的是创建一个二维数组,该数组将表示用元组坐标描述的矩阵,然后按顺序迭代它。 如果我使用字典,我无法保证对键的迭代将按顺序进行 -> (0,0) (0,1) (0,2) (1,0) (1,1) (1,2 ) (2,0) (2,1) (2,2)

谁能帮忙?

【问题讨论】:

    标签: python list tuples


    【解决方案1】:

    您创建了一个一维列表l 并希望将其用作二维列表。 这就是您收到索引错误的原因。

    您有以下选择: 创建一个映射并使用元组 t 作为索引:

    l = {}
    l[t] = something
    

    你会得到 l 中的条目:

    {(1, 1): something}
    

    如果您想要传统的数组结构,我建议您查看numpy。使用 numpy,您可以获得具有“传统”索引的 n 维数组。

    正如我提到的使用 numpy,

    使用 numpy,您可以创建一个二维数组,填充零或一或... 您可以根据需要使用索引 [x,y] 填充任何所需的值。 当然,您可以将行和列或整个数组作为列表进行迭代。

    【讨论】:

      【解决方案2】:

      给出的 dict 解决方案可能最适合大多数用途。对于按顺序遍历键的问题,通常您会改为遍历 坐标空间,而不是 dict 键,这与列表列表的方式完全相同。使用 .get 您可以指定用于空白单元格的默认值,或者使用“collections.defaultdict”在字典创建时定义默认值。例如。

      for y in range(10):
          for x in range(10):
              value = mydict.get((x,y), some_default_value)
              # or just "value = mydict[x,y]" if used defaultdict
      

      如果你确实需要一个实际的列表列表,你可以直接如下构造它:

      max_x, max_y = map(max, zip(*tuples))
      l=[[something if (x,y) in tuples else 0 for y in range(max_y+1)] 
           for x in xrange(max_x+1)]
      

      如果元组列表可能很长,出于性能原因,您可能希望使用集合进行查找,因为“(x,y) in tuples”执行列表扫描,而不是通过哈希快速查找.即,将第二行更改为:

      tuple_set = set(tuples)
      l=[[something if (x,y) in tuple_set else 0 for y in range(max_y+1)] 
           for x in xrange(max_x+1)]
      

      【讨论】:

        【解决方案3】:

        “但据我所知字典不能按键排序”到底是什么意思?

        虽然这与“排序字典”并不完全相同,但您可以轻松地将字典转换为列表,按键排序,这似乎是您所追求的:

        >>> tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
        >>> l = {}
        >>> for t in tuples:
        ...    l[t] = "something"
        >>> sorted(l) # equivalent to sorted(l.keys())
        [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)]
        >>> sorted(l.items()) # make a list of (key, value) tuples, and sort by key
        [((0, 0), 'something'), ((0, 1), 'something'), ((1, 0), 'something'), ((1, 1), 'something'), ((2, 1), 'something')]    
        

        (我把something 变成字符串“something”只是为了让代码工作)

        但是,要在您的情况下使用它(如果我理解正确的话),您仍然需要为字典填充 None 值或每个“空”坐标元组的值)

        【讨论】:

        • 对我来说应该很明显可以比较元组,并且当您按键对字典进行排序时(即元组),您将获得与按行然后按单元对矩阵进行排序一样的排序:) 谢谢。
        【解决方案4】:

        不,您不能创建有间隙的列表。但是您可以使用元组键创建字典:

        tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
        l = {}
        for t in tuples:
            l[t] = something
        

        更新: 尝试使用NumPy,它提供了对矩阵和数组的广泛操作。引用站点上可用的 NumPy 上的免费 pfd(3.4.3 平面迭代器索引):“如前所述,X.flat 返回一个迭代器,它将迭代整个数组(以 C 连续样式与最后一个索引变化最快”。看起来像你需要的。

        【讨论】:

        • 我想说你可以创建一个有间隙的列表,但你不应该在这种情况下。
        • 好的,感谢您的提示,但之后我该如何对列表进行排序?
        • 请注意,这个字典只能被元组索引——如果你想找到第一个偏移量为 t[0] 的东西,那么你就不走运了。目前尚不清楚您的预期用途是什么,所以这可能没问题。
        • 说实话,我不知道如何创建有间隙的列表。我知道 NumPy 支持稀疏结构。你是这个意思还是别的意思?
        • 嗯,dict 在设计上是不可排序的。你到底是什么意思?
        【解决方案5】:

        扩展Nathan的答案,

        tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
        x = max(tuples, key = lambda z : z[0])[0] + 1
        y = max(tuples, key = lambda z : z[1])[1] + 1
        l = [[None] * y for i in range(x)]
        

        然后你就可以为所欲为

        【讨论】:

          【解决方案6】:

          您应该查看 dicts 以获取类似的内容。

          for t in tuples:
            if not l.has_key(t[0]):
              l[t[0]] = {}
            l[t[0]][t[1]] = something
          

          不过,迭代 dict 与迭代列表有点不同。您将拥有 keys()、values() 和 items() 函数来帮助解决这个问题。

          编辑:尝试这样的订购:

          for x in sorted(l.keys()):
             for y in sorted(l[x].keys()):
                 print l[x][y]
          

          【讨论】:

          • 是的,使用元组作为索引可能更好:)
          • 我不同意使用元组索引 - 这取决于填充字典后的预期用法。
          • 问题将分解的元组显示为嵌套列表的两部分索引。除非你有一个合适的矩阵,否则两部分的列表结构很少是你想要的。通常你希望元组作为索引。
          • 我确实有一个合适的矩阵。有 N*M 个元组,其中 N 是第一个元组成员的最大值,M 是所有元组中第二个元组成员的最大值。
          • @Blair Conrad:是的,这取决于使用情况,因此我说“可能更好” - 或者更确切地说,我说“可能”,但这是一个错字:P
          【解决方案7】:

          如果你事先知道你的尺寸,你可以制作一个这样的列表列表

          >>> x = 3
          >>> y = 3
          >>> l = [[None] * x for i in range(y)]
          >>> l
          [[None, None, None], [None, None, None], [None, None, None]]
          

          然后您可以按照最初的建议进行迭代。

          【讨论】:

          • @Greg,这会给您带来指针问题。当您更新 l[0][0] 时,它也会将 l[1][0] 和 l[2][0] 更新为相同的值。
          【解决方案8】:

          我认为您只声明了一个一维列表。

          我认为您将其声明为

          l = [][]
          

          编辑:这是语法错误

          >>> l = [][]
            File "<stdin>", line 1
              l = [][]
                     ^
          SyntaxError: invalid syntax
          >>> 
          

          【讨论】:

            【解决方案9】:

            如前所述,您不能制作带有空格的列表,而字典可能是这里更好的选择。诀窍是确保l[t[0]] 在您将某物放在t[1] 的位置时存在。为此,我会使用defaultdict

            import collections
            tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
            l = collections.defaultdict(dict)
            for t in tuples:
                l[t[0]][t[1]] = something
            

            由于l 是一个默认字典,如果l[t[0]] 不存在,它将创建一个空字典供您将something 放在t[1] 的位置。

            注意:这最终与@unwesen 的答案相同,没有手动检查内部字典是否存在的小麻烦。把它归结为并发回答。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-12-04
              • 1970-01-01
              • 1970-01-01
              • 2011-03-27
              • 2021-03-11
              • 2015-08-09
              • 2021-05-28
              • 1970-01-01
              相关资源
              最近更新 更多