1

みんな、2つの入力(aとb)が同じデータ構造を持っているかどうかをテストする関数を次のように書きました:

print same_structure([1, 0, 1], [a, b, c])
#>>> True
#print same_structure([1, [0], 1], [2, 5, 3])
>>> False
#print same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['d', 'e']]]])
>>> True  
#print same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['de']]]])
>>> False

この関数は (私の実装では) 再帰を使用する必要があります。私は再帰の初心者であり、再帰的に考えるのはまだ難しいです。さらに、答えをごまかすのを避けるために、私は自分の(乱雑な)コードを使用し、それを通じて再帰呼び出しの使用法を学びたいと思います(このコード行を使用:「same_structure return (a [i], b [e])」を適切に使用) )。誰かが以下のコードで再帰を適切に使用する方法を示すことができますか? 助けてくれてありがとう!!!

def is_list(p):
return isinstance(p, list)

def same_structure(a,b):
    if not is_list(a) and not is_list(b):
        print '#1'
        return True
    else:
        if is_list(a) and is_list(b):
            print '#2'
            if len(a) != len(b):
                print '#3'
                return False
            if len(a) == len(b):
                print '#4'
                for e in range(len(a)):
                    print 'e = ', e, 'a[e]= ', a[e], 'b[e]=', b[e]
                    return same_structure(a[e], b[e])           
        else:
            return False
4

3 に答える 3

2

このソリューションを試してみてください。すべての例で機能し、再帰的な関数型プログラミング スタイルで記述されていますがzipall、 などを使用せずにスライスのみを使用して、各ステップでリストのサイズを縮小します。

def same_structure(a, b):
    if a == [] or b == []:
        return a == b
    elif is_list(a[0]) != is_list(b[0]):
        return False
    elif not is_list(a[0]):
        return same_structure(a[1:], b[1:])
    else:
        return same_structure(a[0], b[0]) and same_structure(a[1:], b[1:])
于 2012-04-06T19:52:55.097 に答える
2

以下の作品:

def same_structure(a, b):
    if isinstance(a, list) and isinstance(b, list) and len(a) == len(b):
        return all(same_structure(A, B) for A, B in zip(a, b))
    return (not isinstance(a, list) and not isinstance(b, list))

再帰関数を作成するときは、まず、再帰を呼び出す代わりに値を返すだけの基本ケースを考え出す必要があります。ここでの基本ケースは、次の条件のいずれかです。

  • aリストでリストでbない、またはその逆: False を返す
  • abはどちらもリストですが、長さが異なります: False を返します
  • どちらでもない、aまたはbリストではない: True を返す

aとが両方ともリストで、それらが同じ長さである場合b、これらのリストの各要素を再帰的にチェックする必要があります。 zip(a, b)は、各リストの要素をまとめて反復処理する便利な方法を提供します。same_structure()任意の 2 つのサブ要素で の結果が False の場合、関数全体が False を返すようにします。これが使用される理由all()です。慣れていない場合はall()、次のループと同等です (ただし、より効率的です)。

match = True
for A, B in zip(a, b):
    if not same_structure(A, B):
        match = False
        break
return match

あまり変更せずに関数を書き直す方法は次のとおりです。ロジックは実際には私のソリューションと非常に似ていprint '#4'ますが、そのループから戻るのが早すぎます。

def same_structure(a,b):
    if not is_list(a) and not is_list(b):
        print '#1'
        return True
    else:
        if is_list(a) and is_list(b):
            print '#2'
            if len(a) != len(b):
                print '#3'
                return False
            if len(a) == len(b):
                print '#4'
                for e in range(len(a)):
                    print 'e = ', e, 'a[e]= ', a[e], 'b[e]=', b[e]
                    if not same_structure(a[e], b[e]):
                        return False
                return True        
        else:
            return False
于 2012-04-06T19:29:40.217 に答える
1

すぐに戻ってくるので、最初の再帰呼び出しだけを行っています。

あなたが何をしたいのか理解できたら、サブ要素で same_structure を呼び出し、それが戻り値であることを確認する必要があります(すぐに返すのではありません)。いずれかの呼び出しの結果が false の場合は false を返し、それ以外の場合は true を返します。

于 2012-04-06T19:30:43.527 に答える