将元组转换为列表并返回


206

我目前正在使用平铺地图为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

但是由于级别存储在元组中,因此我无法更改不同块的值。如何轻松更改级别中的不同值?


12
不要使用元组,只需从头开始使用列表。如果您的代码量很大,或者必须继续转换,它可能会真的减慢您的代码
jamylak 2013年

4
从一开始就使用列表而不是元组怎么样?
Krzysztof Bujniewicz

4
@ user2133308 btw只是一个兼容性说明,您应该使用整数除法,//而不仅仅是/因为在Python 3 /中将执行浮点除法并弄乱您的代码。
jamylak

Answers:


284

将元组转换为列表:

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

5
这对我不起作用。如果我在第一个块中运行代码以通过将t传递给list()来将元组t转换为列表,则会收到错误消息:“ ***参数错误:'(t)'”这似乎发生在我只有在调试时。还是很困惑。
吉米

4
@Jimmy这是因为list是调试器命令,请p list(...)改为运行。
moritz

74

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

[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

2
NumPy是使用Python进行科学计算的基本软件包。NumPy的主要对象是齐次多维数组。它是由相同整数组成的元素表(通常为数字),由正整数元组索引。
pradyunsg

24

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

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

要么

level1 = map(list, level1)

并进行相应的修改。

但是一个numpy的数组更酷。


18

将元组转换为列表

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

方法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 = [list(row) for row in level1]

print(level1)

方法2:

level1 = map(list,level1)

print(list(level1))

方法1--0.0019991397857666016秒-

方法2--0.0010001659393310547秒-


14

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

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)

5

两种答案都不错,但有一点建议:

元组是不可变的,这意味着它们不能更改。因此,如果需要处理数据,最好将数据存储在列表中,这样可以减少不必要的开销。

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

另外如建议使用numpy数组是一个更好的选择


您还应该在此答案中写下内容,这numpy将为处理此类数据提供最快的解决方案。
jamylak

当然,即使在处理数据时,也可以使用不可变的数据结构,例如元组。函数式编程的整个前提以及所有这些都主要建立在数据的持久性上。但是,当然,在Python土地上,您可能想与群众
同行

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)

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的情况下有效。如果需要更多值,则必须合并几个位,这会使问题变得更加复杂。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.