2013-04-30 30 views
98

Aktualnie pracuję nad edytorem map dla gry w pygame, używając map kafelków. Poziom jest zbudowany z bloków w następującej strukturze (choć znacznie większy):Konwersja krotki do listy iz powrotem

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

gdzie „1” oznacza blok to ściana i „0” to blok to puste powietrze.

Poniższy kod jest w zasadzie jeden obsługi zmianę typu bloku:

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

Ale ponieważ poziom jest przechowywany w krotce, jestem w stanie zmienić wartości poszczególnych bloków. W jaki sposób mogę łatwo zmienić różne wartości na tym poziomie?

Edytuj: Rozwiązane! Dziękujemy

+9

nie używają krotki, wystarczy użyć listę od początku. To może naprawdę spowolnić twój kod, jeśli twój poziom jest ogromny, jeśli będziesz musiał je dalej konwertować – jamylak

+3

jak od razu zacząć od list zamiast krotek? –

+3

@ user2133308 btw tylko notatkę kompatybilności, powinieneś używać liczb całkowitych '//' zamiast tylko '/', ponieważ w Pythonie 3 '/' wykona podział zmiennoprzecinkowy i zepsuje twój kod. – jamylak

Odpowiedz

17

Możesz mieć listę list. Konwersja krotka krotek do listy list z wykorzystaniem:

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

lub

level1 = map(list, level1) 

i modyfikować je odpowiednio.

Ale numpy array jest chłodniejszy.

50

Masz krotkę krotek.
Aby przekonwertować każdy krotka do listy:

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

--- LUB ---

map(list, level) 

A po zakończeniu edycji, po prostu przekonwertować je z powrotem:

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

--- LUB --- (Dzięki @jamylak)

tuple(itertools.imap(tuple, edited)) 

Można również użyć numpy tablicy:

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

do manipulowania:

if clicked[0] == 1: 
    x = (mousey + cameraY) // 60 # For readability 
    y = (mousex + cameraX) // 60 # For readability 
    a[x][y] = 1 
+0

co to jest tablica numpy? wyjaśnij proszę .. – eRaisedToX

+0

NumPy to podstawowy pakiet do obliczeń naukowych w Pythonie. Głównym obiektem NumPy jest jednorodna tablica wielowymiarowa. Jest to tabela elementów (zwykle liczb), wszystkie tego samego typu, indeksowane krotką dodatnich liczb całkowitych. – pradyunsg

4

Obie odpowiedzi są dobre, ale trochę rada:

Krotki są niezmienne, co oznacza, że ​​nie można ich zmienić. Jeśli więc chcesz manipulować danymi, lepiej jest przechowywać dane na liście, co zmniejszy niepotrzebne obciążenie.

W twoim przypadku wyodrębnij dane do listy, jak pokazano przez eumiro, a po modyfikacji stwórz podobną krotkę o podobnej strukturze, co odpowiedź udzielona przez Schoolboy.

również jako sugerowane użyciu numpy tablicy jest lepszym rozwiązaniem

+0

Powinieneś również napisać w tej odpowiedzi, że 'numpy' zapewni najszybsze rozwiązanie do pracy z tego typu danymi. – jamylak

+0

Oczywiście można używać niezmiennych struktur danych, takich jak krotki, nawet podczas manipulowania danymi. Całe założenie programowania funkcjonalnego i wszystko to w dużej mierze opiera się na trwałości danych. Ale oczywiście w kraju Python możesz iść z masami i swobodnie się mutować ... – progo

1

Można znacznie przyspieszyć swoje rzeczy, jeśli używany tylko jedną listę zamiast listy list. Jest to oczywiście możliwe tylko wtedy, gdy wszystkie twoje wewnętrzne listy mają ten sam rozmiar (co jest prawdą w twoim przykładzie, więc po prostu przyjmuję to).

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) 

i może być nawet szybciej, jeśli użył bitfield zamiast listy:

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) 

z

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

Ale to działa tylko wtedy, gdy pola prostu zawierać 0 lub 1 oczywiście. Jeśli potrzebujesz więcej wartości, musisz połączyć kilka bitów, co sprawiłoby, że problem byłby znacznie bardziej skomplikowany.

148

Konwersja krotka do listy:

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

lista Konwersja do krotki:

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

Dlaczego nie spróbujesz przekształcenie jej typ z krotka do listy i vice versa.

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) 
+0

Genialny pomysł! –

10

Aby przekonwertować krotki do listy

(Przecinki brakowało między krotki w danej kwestii, to dodano do zapobiegania komunikat o błędzie)

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

Metoda 2:

level1 = map(list,level1) 

print(list(level1)) 

Metoda 1 wziął --- 0.0019991397857666016 sekund ---

Metoda 2 wziął --- 0.0010001659393310547 sekund ---

Powiązane problemy