A bit hacky but kinda does the trick anyway :) You definitely have your nested lists.
import re
import ast
input = "(TOP (S (NP (PRP I)) (VP (VBP need) (NP (NP (DT a) (NN flight)) (PP (IN from) (NP (NNP Atlanta))) (PP (TO to) (NP (NP (NNP Charlotte)) (NP (NNP North) (NNP Carolina)))) (NP (JJ next) (NNP Monday))))))"
# replaces all brackets by square brackets
# and adds commas when needed
input = input.replace("(", "[")\
.replace(")", "]")\
.replace("] [", "], [")
# places all the words between double quotes
# and appends a comma after each
input = re.sub(r'(\w+)', r'"\1",', input)
# safely evaluates the resulting string
output = ast.literal_eval(input)
print(output)
print(type(output))
# ['TOP', ['S', ['NP', ['PRP', 'I']], ['VP', ['VBP', 'need'], ['NP', ['NP', ['DT', 'a'], ['NN', 'flight']], ['PP', ['IN', 'from'], ['NP', ['NNP', 'Atlanta']]], ['PP', ['TO', 'to'], ['NP', ['NP', ['NNP', 'Charlotte']], ['NP', ['NNP', 'North'], ['NNP', 'Carolina']]]], ['NP', ['JJ', 'next'], ['NNP', 'Monday']]]]]]
# <class 'list'>
Note: for safety reasons, ast.literal_eval() throws an error if the expression contains operators or some kind of logic, so that you can use it without having to check for malicious code first.