Как перебирать список списков и изменять значения элементов?

У меня есть список списков:

game = [['X', 'O', 'O'], ['', '', 'O'], ['', '', '']]

И я бы хотел изменить все значения:

  • Если элемент - «X», установите значение 1.
  • Если элемент равен 'O', установите к 2.
  • Если элемент равен "" (ничего), то установите значение 0 (ноль).

Результатом будет:

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]

Вы хотите предопределить факторизации, например X -> 1, O -> 2 и т. д. (Почти всегда работа, которую не хочет выполнять вручную). Или сработает согласованная факторизация любой?

jpp 25.10.2018 17:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
5
1
1 358
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Попробуйте перечислить список:

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 или другую более элегантную структуру данных

mad_ 25.10.2018 17:29

Это просто с тупой

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 в список.

mad_ 25.10.2018 17:23

Создайте сопоставление 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']]

Самое питоническое решение

John Coleman 25.10.2018 17:20

Зачем создавать новый список, если можно обновить существующий?

mad_ 25.10.2018 17:23

@mad_ Это зависит от требований. Для достаточно маленьких списков использование списка обычно является наиболее кратким и быстрым методом.

Eugene Yarmash 25.10.2018 17:39

@mad_, потому что временная сложность идентична и память может не быть проблемой. [И, если важна память, более подходящей была бы другая структура данных.]

jpp 25.10.2018 17:57

Я бы определил правила в словаре и получил значения и использовал бы по умолчанию 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.

benvc 25.10.2018 18:07

Уже много отличных ответов. Я добавлю один лайнер с использованием 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'.

benvc 25.10.2018 17:56

Согласен, хотя в этом контексте я склоняюсь к явному определению {'': '0'}, поскольку ['X','O','foo'] также вернет ['1','2','0'], что может быть не предполагаемым результатом. Мы не уверены, что OP может захотеть в случае неопределенного x, что тогда будет подпадать под вариант использования .get(x, default_value).

r.ook 25.10.2018 17:59

Нет сомнений в том, что использование допущений по умолчанию может вызвать проблемы. OP, возможно, разрабатывает игру «tic, tac, foo, bar, baz», насколько нам известно :)

benvc 25.10.2018 18:06

Другие вопросы по теме