2017-06-25 7 views
3

私は、zip()メソッドを使用してPythonで2D配列の非常に特定の部分を抽出したいと思います。私はこのような何かを達成するためにジッパーを使用したい:私は面接の練習問題にPythonで以下の2次元配列で働いていますPythonで 'zip()'をstepパラメーターで使用することはできますか?

>>> sub_matrix = list(zip([*grid[0:3]]*3)) 

# Desired output example (Option 1) 
[".","4",".", ".",".","4",".",".","."] 

# Desired output example (Option 2) 
[[".","4","."], 
[".",".","4"], 
[".",".","."]] 

grid = [[".","4",".",".",".",".",".",".","."], 
    [".",".","4",".",".",".",".",".","."], 
    [".",".",".","1",".",".","7",".","."], 
    [".",".",".",".",".",".",".",".","."], 
    [".",".",".","3",".",".",".","6","."], 
    [".",".",".",".",".","6",".","9","."], 
    [".",".",".",".","1",".",".",".","."], 
    [".",".",".",".",".",".","2",".","."], 
    [".",".",".","8",".",".",".",".","."]] 

この問題を解決する方法の1つは、スドクゲームの3 x 3の「領域」に正当な値が含まれるようにすることです。 zip()を使用して、マトリックスの3 x 3部分を素早く抽出したいと思います。たとえば、左上の領域では、テストに4が2回含まれているためテストが失敗します。

>>> sub_grid = grid[0:3] 
    >>> print(sub_grid) 
    [['.', '4', '.', '.', '.', '.', '.', '.', '.'], 
    ['.', '.', '4', '.', '.', '.', '.', '.', '.'], 
    ['.', '.', '.', '1', '.', '.', '7', '.', '.']] 

私はそれを明らかにするために、印刷を少し変更しますが、この時点で、I:私は次のように私は最初の3行を取得するには、グリッドをサブセットすることができます知っている

enter image description here

3つの配列を3つの 'step'を使ってzipしたいので、それぞれの新しい配列は各配列から3つの値を圧縮して次の配列に移動します。

Python3 docs on zipには、これを行う方法についての抜粋がありますが、目的の出力が得られません。

イテラブルの左から右の評価順序が保証されています。 これは、を使用して、データ系列を の長さのグループにクラスタリングするためのイディオムを可能にします。

(後世のために、質問はCodeFights will be hidden until unlockedからである)

すべてのヘルプは大歓迎です。ありがとう。

+1

numpyでは、これは 'grid [0:3、0:3]'となります。 –

答えて

3

ませジップしかし [row[:3] for row in grid[:3]]

+0

非常に良い答えは、ありがとう。チェックボックスをチェックする前に、ジップに関連する回答があるかどうかを確認します。乾杯。 –

2

zipはその方法で、ネストされた構造をステップ実行をサポートしていません。もう1つの答えのもう1つの選択肢は、mapを使用して、これらのスライスを抽出することです。

from operator import itemgetter 
list(map(itemgetter(0, 1, 2), grid[0:3])) 

または、ご希望の場合:

list(map(lambda x: x[0:3], grid[0:3])) 

あなたはpython2を使用している場合は、余分なlist(...)をドロップすることができます。

どのようなテクニックを使用するのか、理由は、thisのスレッドをご覧ください。

出力:;:ステップの説明による

[reduce(lambda a, b: a+b, item) for l in [zip(*row) for row in zip(*[iter([zip(*[iter(row)]*3) for row in grid])]*3)] for item in l] 

ステップ

レッツ・

[('.', '4', '.'), ('.', '.', '4'), ('.', '.', '.')] 
1

TL DR

ブロックを取得するには、このワンライナーを実行しますzipを使用する方法を初めて目:

chunks = [zip(*[iter(row)]*3) for row in grid] 

[ 
    [('.', '4', '.'), ('.', '.', '.'), ('.', '.', '.')], 
    [('.', '.', '4'), ('.', '.', '.'), ('.', '.', '.')], 
    [('.', '.', '.'), ('1', '.', '.'), ('7', '.', '.')], 
    [('.', '.', '.'), ('.', '.', '.'), ('.', '.', '.')], 
    [('.', '.', '.'), ('3', '.', '.'), ('.', '6', '.')], 
    [('.', '.', '.'), ('.', '.', '6'), ('.', '9', '.')], 
    [('.', '.', '.'), ('.', '1', '.'), ('.', '.', '.')], 
    [('.', '.', '.'), ('.', '.', '.'), ('2', '.', '.')], 
    [('.', '.', '.'), ('8', '.', '.'), ('.', '.', '.')] 
] 

あなたは、各列がサイズ3のチャンクに分割しまった方法を参照してください。行を分割して実行する必要があります。

blocks = zip(*[iter(chunks)]*3) 

[ 
    (
     [('.', '4', '.'), ('.', '.', '.'), ('.', '.', '.')], 
     [('.', '.', '4'), ('.', '.', '.'), ('.', '.', '.')], 
     [('.', '.', '.'), ('1', '.', '.'), ('7', '.', '.')] 
    ), (
     [('.', '.', '.'), ('.', '.', '.'), ('.', '.', '.')], 
     [('.', '.', '.'), ('3', '.', '.'), ('.', '6', '.')], 
     [('.', '.', '.'), ('.', '.', '6'), ('.', '9', '.')] 
    ), (
     [('.', '.', '.'), ('.', '1', '.'), ('.', '.', '.')], 
     [('.', '.', '.'), ('.', '.', '.'), ('2', '.', '.')], 
     [('.', '.', '.'), ('8', '.', '.'), ('.', '.', '.')] 
    ) 
] 

これは私たちにブロックを与えます。抽出のためには、まずそれらを転置することは理にかなって:

transposed_blocks = [zip(*row) for row in blocks] 

[ 
    [ 
     (('.', '4', '.'), ('.', '.', '4'), ('.', '.', '.')), 
     (('.', '.', '.'), ('.', '.', '.'), ('1', '.', '.')), 
     (('.', '.', '.'), ('.', '.', '.'), ('7', '.', '.')) 
    ], [ 
     (('.', '.', '.'), ('.', '.', '.'), ('.', '.', '.')), 
     (('.', '.', '.'), ('3', '.', '.'), ('.', '.', '6')), 
     (('.', '.', '.'), ('.', '6', '.'), ('.', '9', '.')) 
    ], [ 
     (('.', '.', '.'), ('.', '.', '.'), ('.', '.', '.')), 
     (('.', '1', '.'), ('.', '.', '.'), ('8', '.', '.')), 
     (('.', '.', '.'), ('2', '.', '.'), ('.', '.', '.')) 
    ] 
] 

あなたは、各ブロックは独自の行に今どのように参照してください。最後のステップは、各行を1つのリストにマージすることです。

blocks_as_list = [reduce(lambda a, b: a+b, item) 
        for l in transposed_blocks for item in l] 

[ 
    ('.', '4', '.', '.', '.', '4', '.', '.', '.'), 
    ('.', '.', '.', '.', '.', '.', '1', '.', '.'), 
    ('.', '.', '.', '.', '.', '.', '7', '.', '.'), 
    ('.', '.', '.', '.', '.', '.', '.', '.', '.'), 
    ('.', '.', '.', '3', '.', '.', '.', '.', '6'), 
    ('.', '.', '.', '.', '6', '.', '.', '9', '.'), 
    ('.', '.', '.', '.', '.', '.', '.', '.', '.'), 
    ('.', '1', '.', '.', '.', '.', '8', '.', '.'), 
    ('.', '.', '.', '2', '.', '.', '.', '.', '.') 
] 

そして、すべてのブロックのリストになります。今度はそれらをスドクのルールと照らし合わせてチェックすることができます。

関連する問題