2017-09-04 9 views
4

シンプルなネストされていないタプルを受け取り、動作し、返す関数を書いた。タプルを展開して再パックする(Python 2.x)

例えば:

myfun((1,2,3,4)): 
... -> logic 
return (1,2,3,4) -> the numbers can change, but the shape will be the same 

ロジックモノ次元タプルでのみ動作しますが、概念的にネストの各レベルについて同じであるので。 ((1,2,(3,)),(4,))のようなネストされたタプルを平文(1,2,3,4)に変換してから((1,2,(3,)),(4,))に変換する方法があるかどうか疑問に思っていました。

基本的には、一般的な入力タプルをアンパックして処理し、その結果を指定されたものと同じ形にパックすることが必要です。

このようなタスクを達成するためのPythonの方法はありますか?

おそらく、アンパックは再帰で解決できますが、「再パック」の部分についてはわかりません。これは、再梱包のために働く必要が

+0

平滑化部分:https://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists。再パッキング側では、 '((t [0]、t [1]、(t [2])))、(t [3]、))'というタプルを作成するだけです。 – DyZ

+0

して、平坦化部分が実際に再帰的だったように見えます。しかしそれがそうであるように、それはタプルの元の構造についての情報を保持しないでしょう:/ – darkpirate

答えて

2

アンパックはその難しいことではありません。

def unpack(parent): 
    for child in parent: 
     if type(child) == tuple: 
      yield from unpack(child) 
     else: 
      yield child 

例えば、トリックを行うことができます。

再梱包はやや難解です。

def repack(structured, flat): 
    output = [] 
    global flatlist 
    flatlist = list(flat) 
    for child in structured: 
     if type(child) == tuple: 
      output.append(repack(child, flatlist)) 
     else: 
      output.append(flatlist.pop(0)) 

    return tuple(output) 
使用例は次のとおりです:私は、私は怖い、動作しますが、非常にニシキヘビされていない、以下を思い付いた

nested = ((1, 2, (3,)), (4,)) 
plain = tuple(unpack(nested)) 
renested = repack(nested, plain) 

・ホープ、このことができます!

+0

それは確かにします!ありがとうございました。 – darkpirate

+0

私の喜び。構造体をアンパックする際に構造体を記録し、その記録された構造体を再利用して反復せずに再パックする方法があります。ある日、楽しい演習になるかもしれませんが、今は就寝時間です。 :-) –

+0

ええ、それはちょうど再帰のレベルを保存することの問題です...多分私はそれについてもう少し考えてみましょう – darkpirate

2

x = (1,(2,3),(4,(5,6))) 
y = (9,8,7,6,5,4) 

def map_shape(x, y, start=0): 
    if type(x) == tuple: 
     l = [] 
     for item in x: 
      mapped, n_item = map_shape(item, y[start:]) 
      start += n_item 
      l.append(mapped) 
     return tuple(l), start 
    else: 
     return y[start], start+1 

map_shape(x,y)[0] 

出力:

(9, (8, 7), (6, (5, 4))) 
+0

私は似たような何かを念頭に置いて、より少ない "C-ish" tbhを望んでいました。しかし、これは確かに解決策です! Ty – darkpirate

1

私のバージョンを送信します。同じ機能を使用してリストをフラット化し、再構成します。 flatNoneの場合、それは平坦化され、そうでない場合は、タプルを生成することによって再構成される。

import collections 


def restructure(original, flat=None): 
    for el in original: 
     if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)): 
      if flat: 
       yield tuple(restructure(el, flat)) 
      else: 
       yield from restructure(el) 
     else: 
      yield next(flat) if flat else el 


def gen(): 
    i = 0 
    while True: 
     yield i 
     i += 1 


def myfun(iterable): 
    flat = tuple(restructure(iterable)) 
    # your transformation .. 
    flat = gen() # assigning infinite number generator for testing 
    return restructure(iterable, flat=iter(flat)) 


x = (1, (2, 3), (4, (5, 6))) 
print(tuple(y for y in myfun(x))) # (0, (1, 2), (3, (4, 5))) 
+0

非常に興味深いアイデア! – darkpirate

+0

... 10行目から何が得られますか?収穫後に使用されたものを見たことはありません。 – darkpirate

+0

はこのpython 3.xですか?ちょっと...私は2.xを使用していることを忘れて – darkpirate

関連する問題