Grubu listeye ve geri dönüştür


207

Şu anda döşeme oyunlarını kullanarak pygame'de bir oyun için bir harita editörü üzerinde çalışıyorum. Seviye, aşağıdaki yapıdaki bloklardan oluşur (çok daha büyük olsa da):

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

burada "1" duvar olan bir blok ve "0" boş hava olan bir bloktur.

Aşağıdaki kod temel olarak blok tipi değişikliğini yöneten koddur:

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

Ancak seviye bir demet içinde saklandığından, farklı blokların değerlerini değiştiremiyorum. Seviyedeki farklı değerleri kolay bir şekilde nasıl değiştirebilirim?


12
bir demet kullanmayın, sadece en baştan bir liste kullanın. Seviyeniz büyükse, kodlarınızı dönüştürmeye devam etmeniz gerekiyorsa kodunuzu gerçekten yavaşlatabilir
jamylak

4
en başından itibaren tuples yerine listelere gitmeye ne dersiniz?
Krzysztof Bujniewicz

4
@ user2133308 btw sadece bir uyumluluk notu, //sadece /Python 3'te /kayan nokta bölme gerçekleştireceği ve kodunuzu vidalayacağı için tamsayı bölmesini kullanmalısınız .
jamylak

Yanıtlar:


285

Tuple'i listeye dönüştür:

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

Listeyi tuple'e dönüştür:

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

6
Bu benim için çalışmıyor. Eğer t bloğunu listeye () ileterek t parçasını bir listeye dönüştürmek için ilk bloktaki kodu çalıştırırsam, bir hata mesajı alıyorum: "*** Argümandaki hata: '(t)'" sadece hata ayıklama sırasında beni. Hala kafam karıştı.
Jimmy

5
@Jimmy, bunun nedeni listenin bir hata ayıklayıcı komutu olması, p list(...)bunun yerine çalıştırılmasıdır .
moritz

74

Bir demet tutam var.
Her parçayı bir listeye dönüştürmek için:

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

--- VEYA ---

map(list, level)

Düzenlemeyi bitirdikten sonra, bunları geri dönüştürmeniz yeterlidir:

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

--- VEYA --- (Teşekkürler @jamylak)

tuple(itertools.imap(tuple, edited))

Ayrıca bir numpy dizisi kullanabilirsiniz:

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

Manipülasyon için:

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

2
NumPy, Python ile bilimsel hesaplama için temel pakettir. NumPy'nin ana hedefi homojen çok boyutlu dizidir. Bir dizi pozitif tamsayı tarafından endekslenen, aynı türden bir elemanlar tablosudur (genellikle sayılar).
pradyunsg

24

Listelerin bir listesi olabilir. Tuples demetinizi kullanarak bir liste listesine dönüştürün:

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

veya

level1 = map(list, level1)

ve uygun şekilde değiştirin.

Ancak numpy dizisi daha havalı.


18

Tuples'ı listeye dönüştürmek için

(Verilen sorudaki tupeller arasında virgül yoktu, hata mesajını önlemek için eklendi)

Yöntem 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)

Yöntem 2:

level1 = map(list,level1)

print(list(level1))

Yöntem 1 --- 0.0019991397857666016 saniye aldı ---

Yöntem 2 --- 0.0010001659393310547 saniye aldı ---


14

Neden türünü bir gruptan listeye veya tam tersine dönüştürmeye çalışmıyorsunuz?

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

Her iki cevap da iyidir, ancak küçük bir tavsiye:

Tupller değişmez, bu da değiştirilemeyecekleri anlamına gelir. Bu nedenle, verileri manipüle etmeniz gerekiyorsa, verileri bir listede saklamak daha iyidir, gereksiz ek yükü azaltacaktır.

Sizin durumunuzda, verileri eumiro tarafından gösterildiği gibi bir listeye çıkarın ve değiştirdikten sonra Schoolboy tarafından verilen cevaba benzer bir grup oluşturun.

Ayrıca numpy dizisinin kullanılması önerildiği gibi daha iyi bir seçenektir


Ayrıca numpy, bu tür verilerle çalışmak için en hızlı çözümü sağlayacak bu cevaba yazmalısınız .
jamylak

Tabii ki veri işlerken bile tuples gibi değişmez veri yapılarını kullanabilirsiniz. İşlevsel programlamanın tüm dayanağı ve büyük ölçüde verilerin kalıcılığı üzerine inşa edilen her şey. Ama tabii ki, Python topraklarında kitlelerle gitmek ve serbestçe mutasyon yapmak isteyebilirsiniz ...
nperson325681

5

Tuple ve back için liste aşağıdaki gibi yapılabilir

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

Liste listesi yerine yalnızca bir liste kullandıysanız, öğelerinizi önemli ölçüde hızlandırabilirsiniz. Bu elbette sadece tüm iç listeleriniz aynı boyuttaysa mümkündür (bu örnekte doğrudur, bu yüzden bunu varsayıyorum).

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)

Liste yerine bir bit alanı kullandıysanız daha da hızlı olabilirsiniz:

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)

ile

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

Ancak bu yalnızca alanlarınız yalnızca 0 veya 1 içeriyorsa işe yarar. Daha fazla değere ihtiyacınız varsa, sorunu çok daha karmaşık hale getirecek birkaç bit birleştirmeniz gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.