我有一系列代表坐标的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)
有人可以帮忙吗?
答案 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
>>>