4

我有一系列代表坐标的 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 中您可以创建以 index > 0 开头的列表,即创建空白然后填充它们,但似乎您不能。

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

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

任何人都可以帮忙吗?

4

9 回答 9

8

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

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 连续样式,最后一个索引变化最快" . 看起来像你需要的。

于 2009-03-30T11:46:32.850 回答
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]
于 2009-03-30T11:45:52.507 回答
3

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

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

l = {}
l[t] = something

您将在 l 中获得以下条目:

{(1, 1): something}

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

正如我提到的使用numpy,

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

于 2009-03-30T11:51:14.430 回答
2

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

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

然后您可以像最初建议的那样对其进行迭代。

于 2009-03-30T12:03:53.383 回答
1

扩展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)]

然后你可以做任何你想做的事

于 2009-03-30T12:10:48.780 回答
1

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

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

>>> 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 值或每个“空”坐标元组的东西)

于 2009-03-30T12:33:12.363 回答
0

如前所述,您不能制作带有空格的列表,而字典可能是这里更好的选择。诀窍是确保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是 defaultdict,如果l[t[0]]不存在,它将创建一个空 dict 供您放入somethingat position t[1]

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

于 2009-03-30T11:51:00.140 回答
0

给出的 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)]
于 2009-03-30T12:38:32.770 回答
-2

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

我认为您将其声明为

l = [][]

编辑:这是一个语法错误

>>> l = [][]
  File "<stdin>", line 1
    l = [][]
           ^
SyntaxError: invalid syntax
>>> 
于 2009-03-30T11:47:47.993 回答