Сброс вложенного списка при сохранении структуры
Можно ли " очистить "(вложенный) список в 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 ответа:
Вот реализация, которая использует принцип типизации утки:
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]
Преимущество в том, что вы не ограничены структурами/значениями, которые являются
int
s илиlist
s. Эта функция "обнулит" любую изменяемую структуру, поддерживающую индексацию.
>>> 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