Python, как просматривать вложенный список / кортеж, сохраняя иерархию - PullRequest
1 голос
/ 14 февраля 2012

У меня есть список такого типа:

lista = """
<ul>
<li>Arts &amp; Entertainment
<ul>
  <li>Celebrities &amp; Entertainment News</li>
  <li>Comics &amp; Animation
    <ul>
    <li>Anime &amp; Manga</li>
    <li>Cartoons</li>
    <li>Comics</li>
    </ul>
  </li>
 </ul>
</li>
</ul>

"""

, который через Beautiful Soup был преобразован в этот вид кортежей и списков:

[(u'Arts &amp; Entertainment',
  [u'Celebrities &amp; Entertainment News',
   (u'Comics &amp; Animation',
    [u'Anime &amp; Manga', u'Cartoons', u'Comics'])])]

Для того, чтобы перечислить всеэлементы, сохраняющие иерархию Я пытался что-то вроде этого:

myLevel = 0
def orderList2(item):
    global myLevel
    for i in item:
        if isinstance(i, str):
            print str(myLevel) + " " + str(i.encode("utf-8")) + " tuple <br/>"            
        elif isinstance(i, tuple):  
            print str(myLevel) + " " + str(i[0].encode("utf-8")) + " tuple <br/>"
        orderList2(item) 

, но на самом деле это не сработало ...

У вас есть предложения?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 14 февраля 2012

Попробуйте следующее:

def orderList2(item, level=0):
    for i in item:
        if isinstance(i, basestring):
            print level, i.encode('utf-8'), 'tuple <br />'
        elif isinstance(i, tuple):
            orderList2(i, level)
        else:
            orderList2(i, level+1)

Вот вывод для ваших данных:

>>> item = [(u'Arts &amp; Entertainment', [u'Celebrities &amp; Entertainment News', (u'Comics &amp; Animation', [u'Anime &amp; Manga', u'Cartoons', u'Comics'])])]
>>> orderList2(item)
0 Arts &amp; Entertainment tuple <br />
1 Celebrities &amp; Entertainment News tuple <br />
1 Comics &amp; Animation tuple <br />
2 Anime &amp; Manga tuple <br />
2 Cartoons tuple <br />
2 Comics tuple <br />

Обратите внимание, что вместо использования переменной глобального уровня это просто передает текущий уровеньиспользовать в рекурсии.Кроме того, в вашей версии рекурсивный вызов был orderList2(item), когда вы, вероятно, хотели вызвать его с помощью i.Вместо того, чтобы печатать первый элемент в кортежах, он будет просто делать рекурсивный вызов с тем же уровнем, а со списками он будет делать рекурсивный вызов и увеличивать уровень.Наконец, вместо проверки isinstance(i, str) он проверяет basestring, что необходимо, так как строки в ваших данных имеют Unicode.

0 голосов
/ 14 февраля 2012

Ваша вспомогательная функция не совсем правильная. Попробуйте:

def orderList2(myLevel, item):
    for i in item:
    if isinstance(i, str):
        print str(myLevel) + " " + str(i.encode("utf-8")) + " tuple <br/>"            
    elif isinstance(i, tuple):
        visit(myLevel + 1, i)

Это распечатывает строки и, когда он попадает в кортеж, увеличивает уровень и печатает строки в этом кортеже, пока не попадет в другой кортеж, и так далее, и тому подобное. Нет необходимости в глобалах, которые есть в вашем ОП.

А затем назовите это на вашем кортеже верхнего уровня и отпустите в город:

orderList2(0, item)

Это позволяет обрабатывать произвольную глубину вложения в разметке.

...