Сброс вложенного списка при сохранении структуры


Можно ли " очистить "(вложенный) список в python, сохраняя при этом"структуру". Я имею в виду, что если входные данные это

[1,3,4,[5,2,[4,3],3],6,[7,8],9]

Выход будет

[0,0,0,[0,0,[0,0],0],0,[0,0],0]

Где сохраняется фактическая структура списка и сбрасываются только значения.

Контекст: на самом деле нет, этот вопрос просто пришел в голову, и мне было интересно, можно ли это сделать. .

4 2

4 ответа:

Вот реализация, которая использует принцип типизации утки:

In [5]: def clear(seq):
   ...:     for i, item in enumerate(seq):
   ...:         try:
   ...:             clear(item)
   ...:         except TypeError:
   ...:             try:
   ...:                 seq[i] = 0
   ...:             except IndexError, KeyError:
   ...:                 pass
   ...:             

In [6]: s = [1,3,4,[5,2,[4,3],3],6,[7,8],9]

In [9]: clear(s)

In [10]: s
Out[10]: [0, 0, 0, [0, 0, [0, 0], 0], 0, [0, 0], 0]

Преимущество в том, что вы не ограничены структурами/значениями, которые являются ints или lists. Эта функция "обнулит" любую изменяемую структуру, поддерживающую индексацию.

>>> l = [1,3,4,[5,2,[4,3],3],6,[7,8],9]
>>> def reset(lst):
...     return [reset(e) if isinstance(e, list) else 0 for e in lst]
...
>>> l = reset(l)
>>> l
[0, 0, 0, [0, 0, [0, 0], 0], 0, [0, 0], 0]

Я получил это для работы с помощью рекурсии, хотя это немного примитивно.

Примечание: только ints и списки, но может быть любая случайная вложенность. Работает для всех

def set_zero(lst):
    for i,element in enumerate(lst):
        if type(element) != list: lst[i]=0
        else: set_zero(element)

>>> a = [1,3,4,[5,2,[4,3],3],6,[7,8],9]
>>> set_zero(a)
>>> print(a)
[0,0,0,[0,0,[0,0],0],0,[0,0],0]

Кстати, хороший вопрос!

Я смог найти другой метод, который в основном является мошенничеством, но он работает.
Кроме того, это однострочный!!

def set_zero(lst):
    return eval(''.join(str(0) if x.isdigit() else str(x) for x in str(lst)))

>>> a = [1,3,4,[5,2,[4,3],3],6,[7,8],9]
>>> a = set_zero(a)
>>> print(a)
[0,0,0,[0,0,[0,0],0],0,[0,0],0]

Обратная сторона: Это в 3/4 раза медленнее, чем мое предыдущее предложение.

Method 1: ~0.000035 s
Method 2: ~0.000120 s
Я разместил его как другой ответ, так как это совершенно другая концепция. Я могу слить его обратно в свой первый ответ, если хочешь.