2016-01-22 27 views
4

我有一個非結構化列表作爲輸入,我需要在對它們執行多個分析之前變平。一旦我得到每個輸入的結果,將它們放回到原始列表的相同結構中的最佳方式是什麼?基於Python中的模式將單個列表分成多個列表的最佳方式是什麼?

inputList = [["a", ["b","c","d"], [["e"]], "f"],["g"]] 

flattenedList = myFlattenListFunction(inputList) 

# a number of calculations based on the inputList 
# ... 

flattenedResults = [0, 1, 2, 3, 4, 5, 6, 7] 

#What is the best solution to restructure the results to match the inputLists? 
[[1, [2,3,4], [[5]], 6], [7]] 
+0

你能告訴我們更多關於計算的信息嗎?可能不能平坦化? – L3viathan

+1

'chain'不會扁平化任意嵌套的列表(例如'[「e」]') – donkopotamus

+0

@donkopotamus好,請記住,'chain.from_iterable([任何東西])'只會給你任何東西' –

回答

2

下面是使用一個隊列爲輸出值和遞歸的溶液:

def copyStruct(inputStruct, outputValues): 
    return [copyStruct(subList, outputValues) 
      if isinstance(subList, list) 
      else next(outputValues) 
      for subList in inputStruct] 

copyStruct(inputList, iter(flattenedResults)) 
+0

相當於我的。這裏不需要使用隊列,只需使用迭代器和'next(output_values)'! –

+0

啊!感謝@Adam Smith在迭代器上的提示,但我認爲這比使用嵌套函數更清潔一些。 – cr1msonB1ade

+0

對每個人自己:)我更喜歡看到一個乾淨的封閉,而不是一個凌亂的列表比較。無論哪種方式,它的效果很好 –

1

迭代器對此很有用。讓你的原始列表的副本左右,所以你保持它的結構,然後構造你的扁平列表的迭代,遞歸超過您最初的名單(或它的副本),並替換爲下一個元素的每個元素進行迭代的

import copy 

inputList = [["a", ["b","c","d"], [["e"]], "f"],["g"]] 
flat_results = [0, 1, 2, 3, 4, 5, 6, 7] 

def replace(orig, repl): 
    new = copy.deepcopy(orig) 
    repl = iter(repl) 
    def _replace(lst): 
     for idx, el in enumerate(lst): 
      if isinstance(el, list): 
       _replace(el) 
      else: 
       lst[idx] = next(repl) 
    _replace(new) 
    return new 

replace(inputList, flat_results) 
# [[0, [1, 2, 3], [[4]], 5], [6]] 
+0

你可以在一個函數中明智地使用默認參數來做到這一點。 – TigerhawkT3

+0

@ TigerhawkT3可能,但我沒有看到關閉的任何問題。使其看起來更清潔IMO –

0
inputList = [["a", ["b","c","d"], [["e"]], "f"],["g"]] 
flattenedList = magic(inputList) # in python2, `magic` is compiler.ast.flatten 

flatResults = calculations(flattenedList) 

# now for the fun stuff 

resultify(inputList, flatResults) 

def resultify(inputList, flatResults, answer=None): 
    if answer is None: answer = [] 
    if not inputList: return answer 
    for elem in inputList: 
     if not isinstance(elem, list): answer.append(flatResults.pop(0)) 
     else: answer.append(resultify(elem, flatResults, [])) 
    return answer 

輸出:

In [29]: inputList = [["a", ["b","c","d"], [["e"]], "f"],["g"]] 

In [30]: flatResults = [1,2,3,4,5,6,7] 

In [31]: resultify(inputList, flatResults) 
Out[31]: [[1, [2, 3, 4], [[5]], 6], [7]] 
相關問題