Выравнивание с помощью рекурсивной функции

#python #list #function #recursion

#python #Список #функция #рекурсия

Вопрос:

 def flatten(data):
  output=[]
  for item in data:
    if type(item)==list:
      flatten(item)              
      #Correct code: output  = flatten 
    else:
      output.append(item)
      return output


example=[[1,2,3],[4,[5,6]],7,[8,9]]
print("before:",example)
print("after:",flatten(example))
  

Я не знаю, почему мой код неправильный.
Разве список вывода не вызывается снова при вызове рекурсивной функции?
Постоянно ли вызывается пустой список вывода при выполнении написанного мной кода? (Проходит ли выходной список процесс инициализации при каждом его вызове?)

Комментарии:

1. Пожалуйста, исправьте свое форматирование, смотрите Этот вопрос для получения информации о том, как это сделать

2. это можно было бы сделать, используя понимание списка, но я не думаю, что это представляет какой-либо интерес?

3. Измените type(item)==list строку на isinstance(item, list) bcoz — это способ проверки типа данных в python

Ответ №1:

Ваша ошибка в том, что вы используете ‘flatten(item)’, а затем возвращаете выходные данные. Из-за этого несоответствия строка ‘flatten(item)’ абсолютно ничего не делает. Возвращаемое значение не сохраняется. Кроме того, я бы предложил использовать функцию isinstance. Возможным исправлением было бы:

 def flatten(data):
   output = []
   for item in data:
      if (isinstance(item, list)):
         item = flatten(item)
         output =item #or output.extend(item)
      else:
         item.append(item) #or item =[item]
      output.append(item)
   return output
  

РЕДАКТИРОВАТЬ : увидев ваш код снова, я (и, в частности, название функции) Я вижу, вы можете захотеть изменить список «data» и не возвращать новый список «output», значения которого являются сглаженными значениями данных. Решением для этого было бы:

 def flatten(data):
   output = []
   for item in data:
      if (isinstance(item, list)):
         flatten(item)
         output =item #or output.extend(item)
      else:
         item.append(item) #or item =[item]
      output.append(item)
   data = output
  

Краткое объяснение того, почему ваш код неправильный: скажем, что функция чудесным образом работает в строке flatten(item) (то есть функции удается сделать data сглаженным). Функция возвращает новую копию item flattened ( output ) и не изменяет ее (возможно, вы захотите изучить pointers ). Затем item остается неизменным и добавляется в новый список вывода, который вы затем возвращаете.

Мое первое решение будет работать, потому что мы «принимаем» возврат решения (которое имеет свои преимущества, data остается неизменным). Мы сохраняем возвращаемое значение flatten(data) и добавляем его в выходные данные, которые затем возвращаем.

Мое второе решение будет работать, потому что мы «принимаем» изменяющиеся данные. То есть переключение pointer входящих данных в новый список.