在python中填充列表

时间:2009-03-30 11:39:53

标签: python list tuples

我有一系列代表坐标的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超出范围。

我的背景是PHP,我希望在Python中你可以创建以index>开头的列表。 0,即制作间隙,然后将它们填满,但似乎你不能。

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

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

有人可以帮忙吗?

9 个答案:

答案 0 :(得分: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 Flat Iterator索引):“如前所述,X.flat返回一个迭代器,它将遍历整个数组(与最后一个索引呈C-contiguous样式)改变最快的“。看起来像你需要的。

答案 1 :(得分:6)

你应该看看类似的东西。

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]

答案 2 :(得分:3)

您创建了一维列表l,并希望将其用作二维列表。 这就是为什么你得到索引错误。

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

l = {}
l[t] = something

你将在l中获得条目:

{(1, 1): something}

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

正如我提到的那样使用numpy,

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

答案 3 :(得分:2)

如果你知道你手头的尺寸,你可以列出这样的列表

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

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

答案 4 :(得分: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)]

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

答案 5 :(得分:1)

你究竟是什么意思“但据我所知,字典无法按键排序”?

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

>>> 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”以使代码正常工作)

然而,为了适应你的情况(如果我理解正确的话),你仍然需要为每个“空”坐标元组填充无值或字符的字典。

答案 6 :(得分:0)

如前所述,您不能制作带有间隙的列表,字典可能是更好的选择。诀窍在于确保l[t[0]]在您放置位置t[1]时存在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 。为此,我使用defaultdict

l

由于l[t[0]]是默认用户,如果something不存在,则会为您创建一个空字典,以便将t[1]置于{{1}}位置。< / p>

注意:这最终与@ unwesen的答案相同,没有手工检查内部字典存在的轻微乏味。将它归并同时回答。

答案 7 :(得分:0)

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

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

答案 8 :(得分:-2)

我认为你只宣布了一维列表。

我认为您将其声明为

l = [][]

修改:这是语法错误

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