2012-02-21 3 views
1

Можно создать дубликат:
Flatten (an irregular) list of lists in PythonИзвлечение строки из вложенных списков в Python

Я пытаюсь использовать библиотеку NLTK в питона, а более конкретно WordNet корпус, чтобы извлечь все слова в широкой семантической категории, такие как «животное». Мне удалось написать функцию, которая проходит через все категории и извлекает слова в них, но в итоге я получаю огромное количество списков в списках. В списках не предсказуемых длины или глубины, то они выглядят так:

['pet', 'pest', 'mate', 'young', 'stunt', 'giant', ['hen', 'dam', 'filly'], ['head', 'stray', 'dog', ['puppy', 'toy', 'spitz', 'pooch', 'doggy', 'cur', 'mutt', 'pug', 'corgi', ['Peke'], ['chow'], ['feist', 'fice'], ['hound', ['Lhasa', 'cairn']], ['boxer', 'husky']], ['tabby', 'tabby', 'queen', 'Manx', 'tom', 'kitty', 'puss', 'pussy', ['gib']]] 

То, что я хочу, чтобы быть в состоянии захватить каждый из этих строк из этого, и вернуть единый безгнездных список. Любой совет?

+1

Есть также некоторые решения в другом потоке, [Как оптимально превратить многомерный список в один список элементов в Python?] (Http://stackoverflow.com/questions/6679228/how-to- optimally-turn-a-multidimentional-list-in-one-list-of-items-in-pyt) (в частности, я увлекаюсь нерекурсивным решением, которое я разместил в этом потоке). – kindall

+0

Я только что сделал это на Схеме неделю назад, похоже на то, что предлагает Ли-аун. http://stackoverflow.com/questions/9262570/eliminate-inner-paranthesis-runs-into-empty-list-and-doesnt-eliminate-using-con – CppLearner

+0

Это классный трюк, @kindall. –

ответ

3

В общем, когда вам приходится иметь дело с произвольными уровнями гнездования, рекурсивное решение подходит. Списки в списках, парсинг HTML (теги внутри тегов), работающие с файловыми системами (каталоги внутри каталогов) и т.д.

Я не проверял этот код широко, но я считаю, он должен делать то, что вы хотите:

ll = [ 1, 2, 3, [4, 5, [6, 7, 8]]] 

def flatten(input_list): 
    output_list = [] 
    for element in input_list: 
     if type(element) == list: 
      output_list.extend(flatten(element)) 
     else: 
      output_list.append(element) 
    return output_list 

print (flatten(ll)) #prints [1, 2, 3, 4, 5, 6, 7, 8] 

В целом рекурсия очень легко думать, и решения, как правило, очень элегантны (как и выше), но для действительно, действительно глубоко вложенных вещей - думаю, что тысячи уровней глубоки - вы можете столкнуться с проблемами, такими как переполнение стека.

Вообще это не проблема, но я считаю, что рекурсивная функция всегда может * быть преобразованы в петлю (она просто не выглядит так хорошо.)

  • Примечание: Я не врезаться -охота на мою теорию compsci здесь. Кто-то может добавить подробности или исправить меня, если я ошибаюсь.
+0

Спасибо! Я на самом деле пытался сделать что-то довольно похожее, и я думаю, причина, почему это не удалось, я использовал .append(), где вы использовали .extend(). Ваш ответ также немного более понятен (для меня, по крайней мере), чем некоторые из решений в другом потоке. – Marius

+0

Да, 'list.append (x)' добавляет один элемент 'x' в конец списка. 'list.extend (x)' "распаковывает" x ", добавляя каждый из его элементов. Обратите внимание, что 'extend' действительно будет работать для любого итеративного типа, включая списки, dicts и генераторы, а также все с помощью метода' __iter __(). –

+0

Петля == Рекурсия. – CppLearner