Как поменять значение в составном списке
a = [('123',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]],[('45235626t2',)]
for i in a:
for k in i:
for y in k:
if y == '123':
new = y.replace(y, '000')
a[0][0] = new
Хочу поменять ('123',) на ('000',) но при этом вообще меняется вся структура списка, как поменять так чтоб поменялось только '123' в кортеже?
Ответы (2 шт):
И так. Можно пойти многими путями, к примеру, самый относительно простой и чуть более сложный.
Вариант с помощью рекурсии обойти список и поменять значения:
def list_replace(lst: list, value_search, value_replace):
res = []
for item in lst: # Итерируем входной список
if isinstance(item, (list, set, tuple)):
res.append(list_replace(item, value_search, value_replace)) # На этом уровне уходим в список, сет, кортеж глубже
else:
res.append(item if item != value_search else value_replace) # добавляем значение в результирующий список, если совпадает с искомым значением, то меняем его
return type(lst)(res)
a_repl = list_replace(a, '123', '000')
Через библиотеку json с помощью json.dumps() дампим а в строку. В строке делаем замену через replace(). Дальше с помощью json.loads() грузим обратно в переменную.
import json
a = [[('123',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]],[('45235626t2',)]]
a_dump = json.dumps(a)
a_replace = a_dump.replace('"123"', '"000"') # если убрать двойные кавычки внутри, то поменяет все строки, в которых есть 123
a_from_json = json.loads(a_replace)
Вывод:
# список а-исходный
[[('123',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]], [('45235626t2',)]]
# список после json
[[['000'], ['456'], [['12313', '2662'], ['52525', ['4234', ['009999']]]]], [['45235626t2']]]
# список после рекурсии
[[('000',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]], [('45235626t2',)]]
Если у нас переменная а кортеж, то с ним тоже вариант с рекурсией работает:
a = [('123',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]],[('45235626t2',)]
Вывод:
([('000',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]], [('45235626t2',)])
Ну вот примерно так. Рекурсивно перебираем, и если находим кортеж с первым элементом '123', то подменяем его. Нужно учесть, что кортеж неизменен, поэтому менять его можно только целиком. И по этой же причине работать это будет только внутри списка. Кстати, переменная a у вас кортеж из двух элементов, внутри которых уже списки. Поэтому вроде и можно было бы списочное сокращение применить, но вот этот кортеж наружный не даёт.
a = [('123',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]],[('45235626t2',)]
def change_val(items):
for i in range(len(items)):
item = items[i]
if isinstance(item, tuple) and item[0] == '123':
items[i] = ('000', *item[1:])
else:
if isinstance(item, (list,tuple)):
change_val(item)
change_val(a)
print(a)
Вывод:
([('000',), ('456',), [['12313', '2662'], ['52525', ['4234', ['009999']]]]], [('45235626t2',)])
В общем, если возможен вариант "кортеж в кортеже" и подменять нужно будет в нём, то код надо будет ещё переделывать, всё будет ещё сложнее.