2016-02-15 4 views
0

Я искал и нашел вопрос с таким же заголовком также (hereherehereherehere), но я не прошу этого. Я столкнулся с проблемой:Свести нерегулярный список списков в Python рекурсивно

Чтобы написать функцию, чтобы сгладить список. Список содержит другие списки, строки или ints.

И мой код то же

t=[] 
def flatten(aList): 
    for i in aList: 
     if type(i) !=list: 
      t.append(i) 
     else: 
      flatten(i) 

    return t  

Но когда я проверить код тестов:

  1. flatten([[1], [1]]): Средство проверки говорит мне, выход есть [1, 1, 1, 1] но в codeskulptor я получаю правильный выход, который равен [1, 1].
  2. flatten([[[1]], [[[5]]]]): Контроллер сообщает, что выход [1, 1, 1, 1, 1, 2, 3, 3, 2, 1, 0, 4, 5, 6, 7, 1, 5], но в кодексах говорит [1, 5].

Эта проблема существует со многими тестовыми случаями. Затем я проверил свой код в репетиторе python и узнал, что после выполнения оператора if каждый раз, когда возвращается список t и, наконец, когда функция останавливается, возвращается последний отредактированный список t.

Как решить эту проблему, пожалуйста, помогите мне с этим и да, я новичок в python и ничего не знаю об itertools, использовании лямбда-функции, генераторах и т. Д., Поэтому, пожалуйста, расскажите мне в контексте, в котором я могу понять.

+0

Вторая ссылка, которую вы приводите, является рабочим примером этой функции. –

+0

@Morgan Thrapp этот код также не решает мою настоящую проблему –

+0

Просто для стилизации кода: вы должны использовать ['isinstance()'] (https://docs.python.org/3/library/functions.html#isinstance) вместо использования 'type () == type ()'. – albert

ответ

3

Ваш код опирается на глобальный; если контролер дважды вызовет вашу функцию, он получит более длинный список, чем ожидалось:

>>> t = [] 
>>> def flatten(aList): 
...  for i in aList: 
...   if type(i) !=list: 
...    t.append(i) 
...   else: 
...    flatten(i) 
...  return t 
... 
>>> flatten([1, 1]) 
[1, 1] 
>>> flatten([1, 1]) 
[1, 1, 1, 1] 
>>> t # your global, still holding all those values: 
[1, 1, 1, 1] 

Не используйте глобальные переменные. Используйте локальный список, а и расширить его с результатом рекурсивных вызовов:

def flatten(aList): 
    t = [] 
    for i in aList: 
     if not isinstance(i, list): 
      t.append(i) 
     else: 
      t.extend(flatten(i)) 
    return t 

Обратите внимание, что я перешел на использование isinstance() для проверки типа. Эта версия не подвержена утечке общего состояния при следующем вызове:

>>> def flatten(aList): 
...  t = [] 
...  for i in aList: 
...   if not isinstance(i, list): 
...    t.append(i) 
...   else: 
...    t.extend(flatten(i)) 
...  return t 
... 
>>> flatten([1, 1]) 
[1, 1] 
>>> flatten([1, 1]) 
[1, 1] 
>>> flatten([[[1]], [[[5]]]]) 
[1, 5] 
>>> flatten([1, 1, [42, 81]]) 
[1, 1, 42, 81] 
+0

@MorganThrapp: хорошо спросить о хорошей попытке реализовать это. Они спрашивают **, почему ** их попытка не работает. –

+0

@MorganThrapp: Другими словами, найдите хороший обман, когда ответ «не использует глобальное, потому что ваше состояние теперь течет в будущих звонках», и я с радостью проголосую за закрытие. –

+0

@ Martijn Pieters глупый вопрос: почему вы использовали .extend (flatten (i)), почему просто сглаживает (i) работу? –

Смежные вопросы