2015-08-08 5 views
0

Я пытаюсь написать рекурсивную функцию, которая может извлекать вложенные комментарии из представления Reddit. Я использую Python + PrawИзвлечение списка комментариев с потоком рекурсивно

def _get_comments(comments, ret = []): 
    for comment in comments: 
     if len(comment._replies) > 0: 
      return _get_comments(tail(comments), ret + [{ 
       #"body": comment.body, 
       "id": comment.id, 
       "author": str(comment.author), 
       "replies": map(lambda replies: _get_comments(replies, []), [comment._replies]) 
       }]) 
     else: 
      return ret + [{ 
        #"body": comment.body, 
        "id": comment.id, 
        "author": str(comment.author) 
       }] 
    return ret 

def tail(list): 
    return list[1:len(list)] 

И я получаю следующий результат, который является неполным и вложенные массивы:

pprint(_get_comments(s.comments)) 
[{'author': 'wheremydirigiblesat', 
    'id': u'ctuzo4x', 
    'replies': [[{'author': 'rhascal', 
       'id': u'ctvd6jw', 
       'replies': [[{'author': 'xeltius', 'id': u'ctvx1vq'}]]}]]}, 
{'author': 'DemiDualism', 
    'id': u'ctv54qs', 
    'replies': [[{'author': 'rhascal', 
       'id': u'ctv5pm1', 
       'replies': [[{'author': 'blakeb43', 'id': u'ctvdb9c'}]]}]]}, 
{'author': 'Final7C', 'id': u'ctvao9j'}] 

Объект Submission имеет атрибут comments, который представляет собой список Comment объектов. Каждый объект Comment имеет атрибут _replies, который является списком более Comment.

Что мне не хватает? Я дал ему лучший результат - рекурсия тяжелая.

+0

[Мое тестирование Reddit thread] (https://www.reddit.com/r/TrueAskReddit/comments/3g57z2/why_are_humans_fascinated_by_ascending_pertaining/) – uranther

ответ

1

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

Я переименовал вашу функцию в примеры, так как она преобразует комментарии в dicts на самом деле.

Начнем с простого случая, подумайте об этом как: «okey, я хочу иметь функцию, которая способна преобразовать список комментариев в список dicts». Просто простая функция:

def comments_to_dicts(comments): 
    results = [] # create list for results 
    for comment in comments: # iterate over comments 
     item = { 
      "id": comment.id, 
      "author": comment.author, 
     } # create dict from comment 

     results.append(item) # add converted item to results 
    return results # return all converted comments 

И теперь вы хотите, чтобы dict также включал список ответов, преобразованных в dicts. И у вас уже есть функция, которая в состоянии сделать это преобразование, так что давайте просто использовать его и положить результат в item['replies']:

def comments_to_dicts(comments): 
    results = [] # create list for results 
    for comment in comments: # iterate over comments 
     item = { 
      "id": comment.id, 
      "author": comment.author, 
     } # create dict from comment 

     if len(comment._replies) > 0: 
      item["replies"] = comments_to_dicts(comment._replies) # convert replies using the same function 

     results.append(item) # add converted item to results 
    return results # return all converted comments 

Поскольку вы изменили ту же функцию, которую называют, это будет преобразовывать все ответы, независимо от того, как они глубокие. Надеюсь, что более ясно, как работает рекурсия.

+0

Большое спасибо. Это очень ясно, по сравнению с тем, насколько чрезмерно сложно это сделать! – uranther