У меня есть список списков:
game = [['X', 'O', 'O'], ['', '', 'O'], ['', '', '']]
И я бы хотел изменить все значения:
Результатом будет:
game = [['1', '2', '2'], ['0', '0', '2'], ['0', '0', '0']]
Я могу повторять вот так:
for list in game:
for element in list:
...
но чтобы изменить элементы в моем списке списков, это другая история, я могу создать новый список с добавлением, но я получаю что-то вроде [1, 2, 2, 0, 0, 2, 0, 0, 0]






Попробуйте перечислить список:
game = [['X', 'O', 'O'],['', '', 'O'],['', '', '']]
for list in game:
for num,element in enumerate(list):
if element == "X":
list[num] = "1"
if element == "O":
list[num] = "2"
if element == "":
list[num] = "0"
print(game)
Это работает для относительно меньшего количества данных, но может стать более беспорядочным, если нам придется отображать тонны значений. Используйте dict или другую более элегантную структуру данных
Это просто с тупой
import numpy as np
game = np.array(game)
game[game=='X'] = 1
game[game=='O'] = 2
game[game==''] = 0
print(game.tolist())
# [['1', '2', '2'], ['0', '0', '2'], ['0', '0', '0']]
print(game.ravel().tolist())
# ['1', '2', '2', '0', '0', '2', '0', '0', '0']
Я считаю излишним использовать numpy здесь, где не требуется никаких векторных манипуляций. Вы создаете массив numpy из существующего списка -> выполняете операции numpy -> снова конвертируете numpy в список.
Создайте сопоставление dict и выполните итерацию списка (без создания нового списка)
d = {'X':'1','O':'2','':0}
for i in game:
for idx,value in enumerate(i):
i[idx]=d.get(value, str(value))
print(game) #[['1', '2', '2'], ['0', '0', '2'], ['0', '0', '0']]
Если вы хотите создать совершенно новый список
d = {'X':'1','O':'2','':0}
new_list=[]
for i in game:
temp=[]
for idx,value in enumerate(i):
temp.append(d.get(value, str(value)))
new_list.append(temp)
new_list = []
for list in game:
new_sublist = []
for item in list:
...
new_sublist += new_item
new_list += new_sublist
Это должно дать вам 2D-список с вашим подходом, использующим только циклы.
Использование словаря и понимания списка:
>>> game = [['X', 'O', 'O'], ['', '', 'O'], ['', '', '']]
>>> d = {'X': '1', 'O': '2', '': '0'}
>>> [[d[x] for x in row] for row in game]
[['1', '2', '2'], ['0', '0', '2'], ['0', '0', '0']]
Самое питоническое решение
Зачем создавать новый список, если можно обновить существующий?
@mad_ Это зависит от требований. Для достаточно маленьких списков использование списка обычно является наиболее кратким и быстрым методом.
@mad_, потому что временная сложность идентична и память может не быть проблемой. [И, если важна память, более подходящей была бы другая структура данных.]
Я бы определил правила в словаре и получил значения и использовал бы по умолчанию 0 для пустых строк.
Я также использовал понимание списка.
только понимание списка:
new_game = [[rules.get(item, 0) for item in li] for li in game]
Использование вспомогательной функции:
game = [['X', 'O', 'O'],
['', '', 'O'],
['', '', '']]
rules = { 'X': '1', 'O': '2' }
def update_list(li):
return [rules.get(item, 0) for item in li]
new_game = [update_list(li) for li in game]
print (new_game)
# [[1, 2, 2], [0, 0, 2], [0, 0, 0]]
Теперь, когда у вас есть список ответов, который работает над исчерпанием всех возможностей преобразования значений списка списков на основе простого сопоставления, кажется, что было бы упущением не включить решение, использующее map(). Итак, вот оно:
game = [['X', 'O', 'O'], ['', '', 'O'], ['', '', '']]
nums = [list(map(lambda x: '2' if x == 'O' else '1' if x == 'X' else '0', row)) for row in game]
print(nums)
# OUTPUT
# [['1', '2', '2'], ['0', '0', '2'], ['0', '0', '0']]
Посмотрите лучший ответ map() от @Idlehands.
Уже много отличных ответов. Я добавлю один лайнер с использованием map() просто потому, что это весело:
[list(map(lambda x: {'X':'1', 'O':'2', '':'0'}.get(x), i)) for i in game]
# [['1', '2', '2'], ['0', '0', '2'], ['0', '0', '0']]
Объяснение: map(), по сути, применяет функцию поверх переданного объекта i, который является подсписками игры. В этом случае мы хотим применить .get(x) из оценочного словаря к каждой отметке (x) в подсписках (i) в game. В сочетании с пониманием списка он дает вам все преобразованные оценки как новый list из list.
Мне это нравится больше, чем мой ответ с использованием map() (более читаемый). Вы также можете сделать [list(map(lambda x: {'X':'1', 'O':'2'}.get(x, '0'), i)) for i in game] для значения '0' по умолчанию, если вложенные списки содержат любое значение, кроме 'X' или 'O'.
Согласен, хотя в этом контексте я склоняюсь к явному определению {'': '0'}, поскольку ['X','O','foo'] также вернет ['1','2','0'], что может быть не предполагаемым результатом. Мы не уверены, что OP может захотеть в случае неопределенного x, что тогда будет подпадать под вариант использования .get(x, default_value).
Нет сомнений в том, что использование допущений по умолчанию может вызвать проблемы. OP, возможно, разрабатывает игру «tic, tac, foo, bar, baz», насколько нам известно :)
Вы хотите предопределить факторизации, например
X -> 1,O -> 2и т. д. (Почти всегда работа, которую не хочет выполнять вручную). Или сработает согласованная факторизация любой?