Преобразование кортежа в список и обратно
В настоящее время я работаю над редактором карт для игры в 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
Но так как уровень хранится в кортеже, я не могу изменить значения разных блоков. Как мне легко изменить различные значения на уровне?
Ответы
Ответ 1
Преобразовать кортеж в список:
>>> 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')
Ответ 2
У вас есть кортеж кортежей.
Чтобы преобразовать каждый кортеж в список:
[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
Ответ 3
У вас может быть список списков. Преобразуйте кортеж кортежей в список списков, используя:
level1 = [list(row) for row in level1]
или
level1 = map(list, level1)
и соответствующим образом изменить их.
Но массив numpy является более прохладным.
Ответ 4
Чтобы преобразовать кортежи в список
(Запятые отсутствовали между кортежами в заданном вопросе, он был добавлен для предотвращения сообщения об ошибке)
Способ 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 секунд ---
Ответ 5
Почему бы вам не попробовать преобразовать свой тип из кортежа в список и наоборот.
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)
Ответ 6
Оба ответа хороши, но небольшой совет:
Кортежи неизменяемы, что означает, что они не могут быть изменены. Поэтому, если вам нужно манипулировать данными, лучше хранить данные в списке, это уменьшит ненужные служебные данные.
В вашем случае извлеките данные в список, как показано eumiro, и после модификации создайте аналогичный кортеж аналогичной структуры, такой как ответ, предоставленный Schoolboy.
Также, как предложено использование массива numpy, это лучший вариант
Ответ 7
Вы могли бы значительно ускорить работу, если бы вы использовали только один список, а не список списков. Это возможно, конечно, только если все ваши внутренние списки имеют одинаковый размер (что верно в вашем примере, поэтому я просто предполагаю это).
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, конечно. Если вам нужно больше значений, вам придется объединить несколько бит, что значительно затруднит проблему.
Ответ 8
Список к кортежу и обратно можно сделать как ниже
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)