タプルをリストに変換して戻す


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

4
最初からタプルの代わりにリストを使うのはどうですか?
Krzysztof Bujniewicz 2013

4
@ user2133308ところで、単なる互換性の注意事項です。Python3 //では浮動小数点除算が実行されてコードが台無し//なるため、代わりに整数除算を使用する必要があります。
jamylak 2013

回答:


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をリストに変換すると、エラーメッセージ「*** Error in argument: '(t)'」が表示されます。デバッグ中のみ。まだ混乱しています。
ジミー

4
@Jimmyは、リストがデバッガコマンドであるため、p list(...)代わりに実行します。
モリッツ

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 2016

24

リストのリストを持つことができます。以下を使用して、タプルのタプルをリストのリストに変換します。

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

または

level1 = map(list, level1)

それに応じて変更します。

しかし、派手な配列はよりクールです。


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 2013

もちろん、データを操作しているときでも、タプルなどの不変のデータ構造を使用できます。関数型プログラミングのすべての前提と、そのほとんどがデータの永続性に基づいています。しかしもちろん、Pythonの土地では、大衆と一緒に行き、自由に変異させたいと思うかもしれません...
nperson325681 '26

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

リストのリストの代わりに1つのリストだけを使用した場合、ものを劇的にスピードアップできます。もちろん、これは、すべての内部リストが同じサイズの場合にのみ可能です(これは、例で当てはまるため、これを前提としています)。

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が含まれている場合にのみ機能します。さらに多くの値が必要な場合は、いくつかのビットを組み合わせる必要があるため、問題がさらに複雑になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.