Нерекурсивные средства печати списка в Python - PullRequest
2 голосов
/ 22 июля 2009

Есть ли способ выполнить следующее нерекурсивным способом:

my_list = [
    "level 1-1",
    "level 1-2",
    "level 1-3",
        [
            "level 2-1",
            "level 2-2",
            "level 2-3",
            [
                "level 3-1",
                "level 3-2"
            ]
        ],
    "level 1-4",
    "level 1-5"
    ]


def print_list(the_list, indent_level=0):
    for item in the_list:
        if isinstance(item, list):
            print_list(item, indent_level + 1)
        else:
            print "\t" * indent_level, item


print_list(my_list)

Ответы [ 5 ]

4 голосов
/ 22 июля 2009
stack = [(my_list, -1)]
while stack:
    item, level = stack.pop()

    if isinstance(item, list):
        for i in reversed(item):
            stack.append((i, level+1))
    else:
        print "\t" * level, item
2 голосов
/ 22 июля 2009

Вот вариант версии Мартина Лёвиса, который использует for/else вместо ручной перехватки StopIteration и len(stack) вместо отслеживания уровня отступа.

def print_list(the_list):
    stack = [iter(the_list)]
    while stack:
        for item in stack[-1]:
            if isinstance(item, (list, tuple)):
                stack.append(iter(item))
                break
            else:
                print '\t' * (len(stack)-1), item
        else:
            stack.pop()
2 голосов
/ 22 июля 2009
def print_list(the_list, indent_level=0):
    stack = [iter(the_list)]
    while stack:
        try:
            item = stack[-1].next()
        except StopIteration:
            stack.pop()
            indent_level -= 1
            continue
        if isinstance(item, list):
            indent_level += 1
            stack.append(iter(item))
        else:
            print "\t" * indent_level, item
0 голосов
/ 22 июля 2009

Каждый дал решения, которые

  • производство готово
  • использует стек, поэтому имеет ту же проблему, что и рекурсия
  • или пройти список несколько раз

Вот решение боковое решение:)

  • не готово к производству, но весело
  • нет стека или чего-либо в этом роде, списков не видно

-

def my_print(the_list):
    level = -1
    out = []
    levelUp="levelup"
    levelDown="leveldown"

    s =  repr(the_list).replace("', '","\n").replace(
        "', ['", "\n%s\n"%levelUp).replace("['", "\n%s\n"%levelUp).replace(
        "']", "\n%s\n"%levelDown).replace("], '", "\n%s\n"%levelDown)

    for line in s.splitlines():
        if not line: continue
        if line == levelUp:
            level+=1
        elif line == levelDown:
            level-=1
        else:
            print "\t"*level,line

my_print(my_list)

Предполагается, что в тексте вашего списка не будет специальных подстрок.

0 голосов
/ 22 июля 2009

Обратите внимание, что это зависит от входных данных, не содержащих кортежи.

l1 = my_list
done = False

# Repeatedly turn the list elements into tuples of the form
# (indent, item) until there are no more lists.
while not done:
    done = True
    l2 = []
    for item in l1:
        if isinstance(item,tuple):
            indent = item[0]
            item = item[1]
        else:
            indent = 0
        if isinstance(item,list):
            l2.extend( zip( (indent + 1,) * len(item), item) )
            done = False
        else:
            l2.append((indent,item))
    l1 = l2

for indent, item in l1:
    print "\t" * indent, item
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...