2017-12-08 23 views
1

入力として、nレベルまでできるリストが得られ、毎回変わります。私はこのリストと期待される出力をソートしたい、私はリストここPythonリストを再帰的にソート

[[2, 1, 3], 4, [2, 3], 7, 1, [9, [4, 2], 5]] 

を持っている、と仮定すると、最初のソートは、リスト内の要素の合計に基づいて、その後の要素のもと起こっている、ここで

[1, 4, [2, 3], [1, 2, 3], 7, [5, [2, 4], 9]] 

です。

コード:

input_freq = [[2,1,3],4,[2,3],7,1,[9,[4,2],5]] 

res = [] 

def sortFreq(input_freq): 
    elements = [] 
    list_of_elements = [] 

    for each in input_freq: 
     if isinstance(each, list): 
      print "list" 
      list_of_elements.append(each) 
      each.sort() 
     else: 
      elements.append(each) 
      elements.sort() 

    print elements 
    print list_of_elements 

sortFreq(input_freq) 

予想される出力:

[1, 4, [2, 3], [1, 2, 3], 7, [5, [4, 2], 9]] 

が、私のコードは、誤った結果を返します:あなたがにダウンあなたのように動作する必要があります

[[1, 2, 3], [2, 3], [5, 9, [4, 2]]] 
+1

'[9、[4,2]、5]'の合計はいくらですか? *フラット化された*要素の合計、したがって '9 + 4 + 2 + 5 == 20'? –

+1

まず、ネストされたリストの要素の合計を使って、あなたはどこにいても見当たりません。 –

+1

第二に、あなたは "再帰的なやり方"と言っていましたが、反復アルゴリズムを実装しました。それはあなたが目指しているものなのですか? –

答えて

3

をネストされたレベルを最初に作成し、親レベルを再帰呼び出しの戻り値としてソートしますs。

def nested_sort(l): 
    def sort_key(e): 
     if isinstance(e, list): 
      return sum(sort_key(inner) for inner in e) 
     return e 
    return sorted(
     [nested_sort(e) if isinstance(e, list) else e for e in l], 
     key=sort_key) 

ソートキーを再帰的にネストされたリストを合計する持っているので、これはあなたがネストされた多くのを持っている場合、この種の高価なことができます:私はあなたが(並べ替えの場所ではなく)新しいリストを返すようにしたいと仮定するつもりですレベル。その中で、それが合計されているリストのアイデンティティに基づいてキャッシュを追加する価値があるかもしれない:

def nested_sort(l, _sum_cache=None): 
    if _sum_cache is None: 
     _sum_cache = {} 
    def sort_key(e): 
     if isinstance(e, list): 
      e_id = id(e) 
      if e_id not in _sum_cache: 
       _sum_cache[e_id] = sum(sort_key(inner) for inner in e) 
      return _sum_cache[e_id] 
     return e 
    return sorted(
     [nested_sort(e, _sum_cache) if isinstance(e, list) else e for e in l], 
     key=sort_key) 

デモ:

>>> nested_sort([[2, 1, 3], 4, [2, 3], 7, 1, [9, [4, 2], 5]]) 
[1, 4, [2, 3], [1, 2, 3], 7, [5, [2, 4], 9]] 
0

ここでは一度だけ、すべての合計を行うことの利点を持っているソリューションです。それはかなり短いです:

import operator 

def sort_lol(lol): 
    srtd, sums = zip(*sorted((sort_lol(el) if isinstance(el, list) else (el, el) 
           for el in lol), key=operator.itemgetter(1))) 
    return list(srtd), sum(sums) 

lst = [[2,1,3],4,[2,3],7,1,[9,[4,2],5]] 
print(sort_lol(lst)) 

# ([1, 4, [2, 3], [1, 2, 3], 7, [5, [2, 4], 9]], 43) 
# note that the function returns the sorted list and the total (43 here) 
+0

のリストである。しかし、私はそれがタプルを返して、リストを返しません。私はここでデータ構造を変更したくない。 –

+0

@MaheshKariaOops、修正されました。 –