262

我目前正在使用平铺地图为 pygame 中的游戏制作地图编辑器。该级别由以下结构中的块组成(尽管要大得多):

level1 = (
         (1,1,1,1,1,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,1,1,1,1,1))

其中“1”是一堵墙的方块,“0”是一个空的方块。

以下代码基本上是处理块类型更改的代码:

clicked = pygame.mouse.get_pressed()
if clicked[0] == 1:
    currLevel[((mousey+cameraY)/60)][((mousex+cameraX)/60)] = 1

但由于级别存储在元组中,我无法更改不同块的值。如何以简单的方式更改关卡中的不同值?

4

10 回答 10

348

将元组转换为列表:

>>> t = ('my', 'name', 'is', 'mr', 'tuple')
>>> t
('my', 'name', 'is', 'mr', 'tuple')
>>> list(t)
['my', 'name', 'is', 'mr', 'tuple']

将列表转换为元组:

>>> l = ['my', 'name', 'is', 'mr', 'list']
>>> l
['my', 'name', 'is', 'mr', 'list']
>>> tuple(l)
('my', 'name', 'is', 'mr', 'list')
于 2014-05-06T14:27:56.903 回答
87

你有一个元组的元组。
要将每个元组转换为列表:

[list(i) for i in level] # list of lists

- - 或者 - -

map(list, level)

完成编辑后,只需将它们转换回来:

tuple(tuple(i) for i in edited) # tuple of tuples

--- 或者 --- (感谢@jamylak)

tuple(itertools.imap(tuple, edited))

您还可以使用 numpy 数组:

>>> a = numpy.array(level1)
>>> a
array([[1, 1, 1, 1, 1, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 1, 1, 1, 1, 1]])

对于操纵:

if clicked[0] == 1:
    x = (mousey + cameraY) // 60 # For readability
    y = (mousex + cameraX) // 60 # For readability
    a[x][y] = 1
于 2013-04-30T09:38:41.467 回答
27

你可以有一个列表列表。使用以下方法将您的元组元组转换为列表列表:

level1 = [list(row) for row in level1]

或者

level1 = map(list, level1)

并相应地修改它们。

但是一个numpy 数组更酷。

于 2013-04-30T09:37:02.773 回答
20

将元组转换为列表

(给定问题的元组之间缺少逗号,添加它是为了防止出现错误消息)

方法一:

level1 = (
     (1,1,1,1,1,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,1,1,1,1,1))

level1 = [list(row) for row in level1]

print(level1)

方法二:

level1 = map(list,level1)

print(list(level1))

方法 1 耗时 --- 0.0019991397857666016 秒 ---

方法 2 耗时 --- 0.0010001659393310547 秒 ---

于 2015-06-20T02:20:29.910 回答
19

从 Python 3.5 ( PEP 448 -- Additional Unpacking Generalizations ) 开始,可以使用以下文字语法将元组转换为列表:

>>> t = (1,2,3)
>>> lst = [*t]
>>> lst
[1, 2, 3]
>>> *lst,  # back to tuple
(1, 2, 3)

列表推导可用于将元组的元组转换为列表的列表:

>>> level1 = (
...      (1,1,1,1,1,1),
...      (1,0,0,0,0,1),
...      (1,0,0,0,0,1),
...      (1,0,0,0,0,1),
...      (1,0,0,0,0,1),
...      (1,1,1,1,1,1))
>>> level1_list = [[*row] for row in level1]
>>> level1_list
[[1, 1, 1, 1, 1, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 1, 1, 1, 1, 1]]
>>> *((*row,) for row in level1_list),
((1, 1, 1, 1, 1, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 1, 1, 1, 1, 1))
>>> _ == level1
True
于 2020-07-31T12:39:09.687 回答
16

为什么不尝试将其类型从元组转换为列表,反之亦然。

level1 = (
     (1,1,1,1,1,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,1,1,1,1,1))

print(level1)

level1 = list(level1)

print(level1)

level1 = tuple(level1)

print(level1)
于 2015-05-30T17:22:54.423 回答
5

两个答案都很好,但有一点建议:

元组是不可变的,这意味着它们不能更改。所以如果你需要对数据进行操作,最好将数据存储在一个列表中,这样会减少不必要的开销。

在您的情况下,将数据提取到一个列表中,如 eumiro 所示,并在修改后创建一个与 Schoolboy 给出的答案相似的结构相似的元组。

还建议使用 numpy 数组是一个更好的选择

于 2013-04-30T09:51:50.327 回答
5

列表到元组并返回可以如下完成

import ast, sys
input_str = sys.stdin.read()
input_tuple = ast.literal_eval(input_str)

l = list(input_tuple)
l.append('Python')
#print(l)
tuple_2 = tuple(l)

# Make sure to name the final tuple 'tuple_2'
print(tuple_2)
于 2018-12-21T18:44:22.260 回答
2

如果您只使用一个列表而不是列表列表,您可以大大加快您的工作速度。当然,只有当您的所有内部列表都具有相同的大小时,这才是可能的(在您的示例中是正确的,所以我只是假设这一点)。

WIDTH = 6
level1 = [ 1,1,1,1,1,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,1,1,1,1,1 ]
print level1[x + y*WIDTH]  # print value at (x,y)

如果您使用位域而不是列表,您可能会更快:

WIDTH = 8  # better align your width to bytes, eases things later
level1 = 0xFC84848484FC  # bit field representation of the level
print "1" if level1 & mask(x, y) else "0"  # print bit at (x, y)
level1 |= mask(x, y)  # set bit at (x, y)
level1 &= ~mask(x, y)  # clear bit at (x, y)

def mask(x, y):
  return 1 << (WIDTH-x + y*WIDTH)

但这只有在您的字段当然只包含 0 或 1 时才有效。如果您需要更多值,则必须组合几个位,这会使问题变得更加复杂。

于 2013-04-30T10:02:36.257 回答
1

仅使用命令列表对我不起作用。

如果您有一个元组,只需迭代直到您拥有必要的元素,然后附加到列表中。如果您进入元素级别,您可以轻松更改它。

输入:

level1 = (
         (1,1,1,1,1,1),
         (1,0,0,0,0,1),
         (1,0,0,0,0,1),
         (1,0,0,0,0,1),
         (1,0,0,0,0,1),
         (1,1,1,1,1,1))

level1_as_list=[]
for i in level1:
    inside_list=[]
    for j in i:
        inside_list.append(j)
    level1_as_list.append(inside_list)

print(level1_as_list)enter code here

输出:

[[1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1]]
于 2021-02-05T15:24:23.210 回答