1

ネストされたリストをフラット化する演習を行っています。コードはコンソールでは機能しますが、ファイル内では機能しません。何が起こっているのかわかりません。:(

def flatten(nested):
    """
            >>> flatten([2, 9, [2, 1, 13, 2], 8, [2, 6]])
            [2, 9, 2, 1, 13, 2, 8, 2, 6]
            >>> flatten([[9, [7, 1, 13, 2], 8], [7, 6]])
            [9, 7, 1, 13, 2, 8, 7, 6]
            >>> flatten([[9, [7, 1, 13, 2], 8], [2, 6]])
            [9, 7, 1, 13, 2, 8, 2, 6]
            >>> flatten([[5, [5, [1, 5], 5], 5], [5, 6]])
            [5, 5, 1, 5, 5, 5, 5, 6]
    """
    simple = []

    for x in nested:
            if type(x) == type([]):
                    for y in x:
                            simple.append(y)
            else:
                    simple.append(x)
    return simple



if __name__ == '__main__':
    import doctest
    doctest.testmod()

最初はこの演習を再帰的に解こうとしましたが、最初に反復的に試すことにしました。

編集: ファイルで実行すると、元の関数引数 TIA を出力するだけです

4

5 に答える 5

5

問題は、平坦化関数が 1 つのレベルのみを平坦化することです。doctest がエラーを表示する理由は、実際にエラーが発生しているためです。それらはあなたが渡したものではありません。

File "test.py", line 5, in __main__.flatten
Failed example:
    flatten([[9, [7, 1, 13, 2], 8], [7, 6]])
Expected:
    [9, 7, 1, 13, 2, 8, 7, 6]
Got:
    [9, [7, 1, 13, 2], 8, 7, 6]

y追加する代わりに--- flatten も呼び出す再帰的なアプローチを調査する必要があり yます。if type(x) != type([])あなたのベースケースになることができます。

于 2010-07-13T20:09:29.260 に答える
3

「チート」したい場合は、これを行うことができます:

L = [1, 2, [3, 4], 5, 6, [7, 8, [9, 10, 11]]]
s = repr(L)
s = '[' + s.replace('[','').replace(']','') + ']'
L = eval(s)

「通常の」平坦化操作と比較して、どれだけ速いか興味があります...


編集:

簡単なテストでは、データの複雑さに関係なく、不正行為の方法にはほぼ一定の時間がかかりますが、再帰的な解決策では時間がかかることが示されています。

大きい

チート: 7.13282388182
再帰: 2.84676811407

小さい

チート: 7.08800692623
再帰: 0.486098086038

これが私のコードです(そして、より大きなデータセットに本当に興味があります!):

import timeit

L = [1,2,3,
     [46, 100000, 20, 9, 
      [1,2,3, 
       [9, 23, 24, 
        [9, 23, 24, 
         [9, 23, 24, 
          [9, 23, 24, 
           [9, 23, 24, [9, 23, 24, [13], 12],4]]]], 26]]]]

L2 = [1,2,3, [4,5,6]]

def flattencheat(mylist):
    s = repr(L)
    s = '[' + s.replace('[', '').replace(']', '') + ']'
    return eval(s)

def flattencurse(mylist):
    newlist = []
    for val in mylist:
        if not hasattr(val, '__iter__'):
            newlist.append(val)
        else:
            newlist.extend(flattencurse(val))

    return newlist

print "Cheat: ", timeit.timeit('flattencheat(L)', "from __main__ import flattencheat, L", number=100000)
print "Recurse: ", timeit.timeit('flattencurse(L)', 
                                 'from __main__ import flattencurse, L',
                                 number = 100000)
print "Cheat: ", timeit.timeit('flattencheat(L2)', "from __main__ import flattencheat, L2", number=100000)
print "Recurse: ", timeit.timeit('flattencurse(L2)', 
                                 'from __main__ import flattencurse, L2',
                                 number = 100000)
于 2010-07-13T20:27:47.077 に答える
0

あなたのアプリケーションは何もしていません。

Input:  [3,[5, [5, [1, 5], 5], 5], [5, 6]]
Output: [3, 5, [5, [1, 5], 5], 5 ,  5, 6]

再帰などを使用して、完了するまで平坦化を続ける必要があります。シンプルですが、データを 1 つ余分に渡す必要がありtype(x) == type([])ます。flatten(simple)simple

于 2010-07-13T20:15:01.190 に答える
0

@orangeoctopus の答えは正しいと思いますが、「なぜコンソールで機能するのか」という質問を捉えていません。私は推測するつもりです:

コンソールでは機能しません。たまたま機能する入力のサブセットでテストしたと思います。例えば、

>>> flatten([2, 9, [2, 1, 13, 2], 8, [2, 6]])
[2, 9, 2, 1, 13, 2, 8, 2, 6]

動作します!

しかし

>>> flatten([[9, [7, 1, 13, 2], 8], [7, 6]])
[9, [7, 1, 13, 2], 8, 7, 6]

あまりしません。

于 2010-07-13T20:27:09.670 に答える
0

私の答えは@DonaldMinerのものとかなり似ています(実際、私もそれから始めました)が、リスト内の文字列に"["orが含まれ"]"ていると失敗することに気付きました。

たとえば、ここでは機能しません:

["Hello", "World", "A", "[Menu]"]

同様の関数を作成しました (もう少し複雑で、リスト内の文字列に含まれていない場合のみ and を削除し[ます]

from ast import literal_eval
def flatten(to_squash):
    """This will flatten a list, no matter the recursion limit."""
    instring = False
    squashed = []
    index = 0
    print(repr(to_squash))
    for char in repr(to_squash):
        if char == '"' or char == "'":
            instring = not instring
            print(instring, char)
            squashed.append(char)
        elif not instring and char == "[" or not instring and char == "]":
            pass
        else:
            squashed.append(char)
        index += 1

    print("".join([item.strip() for item in squashed]))
    return literal_eval("".join(squashed))

もちろん も使用できますがeval()、どこかからリストを読み取らない場合に限ります (プログラムによって作成されます)。それ以外の場合は、誰かがコマンドを入力するだけで、python がそれを実行します。

于 2014-05-03T19:58:08.317 に答える