3

同じサイズの NumElements の A、B、C、D という 4 つの配列があり、それらの 0 をすべて削除したいと考えています。A にゼロがある場合、B、C、および D にも同じ位置にゼロがあります。だから私は A の要素をループすることを考えていました:

for n in range(NumElements):
    if A[n]==0:
       A.pop(n)
       B.pop(n)
       C.pop(n)
       D.pop(n)

もちろん、配列から 0 をポップするとサイズが小さくなるため、これは機能しません。したがって、A が NumElements-m の長さしかないときに、A[NumElements-1] にアクセスしようとすることになります。配列のコピーを使用する必要があることはわかっていますが、配列は非常に長く、Java 仮想マシンで作業しているため、メモリ消費を低く抑えたいと考えています (質問しないでください :(((( )。また、私は効率的であるが、何よりも読みやすいアプローチが欲しいです (このコードは、私のような Python の読み書きができない人によって維持される必要があるため、KISS が必要です)。

4

6 に答える 6

5
a,b,c,d = [filter(lambda i: i != 0, l) for l in [a,b,c,d]]

0 以外の要素を削除して、各リストをフィルタリングします。

編集、

何が起こっているのかを説明するだけです

Filter は式を取り、リスト内のすべてのもの、つまり True を返さないものすべてに関数を適用することにより、リストを「フィルタリング」します。

ラムダは関数の省略形です

そう

a = [1,2,3,4,5,6,7,8]

def is_even(x):
    return x % 2 == 0
filter(is_even, a)
于 2013-07-19T10:20:13.160 に答える
4

すべて同じ場所にゼロがある場合は、インデックスを逆方向にループし、各リストからそのインデックスを削除します。

for i in reversed(range(NumElements)):
    if not A[i]:
        del A[i], B[i], C[i], D[i]

リストを逆方向にループすることで、インデックスを安定させます (現在のインデックスより後の要素のみ削除され、リストの末尾のみが縮小されます)。の戻り値を使用していないのでlist.pop()(とにかく取得するのは0s だけですよね?)、del代わりにリスト インデックスで使用することもできます。

reversed(range(NumElements))より激しいrange(NumElements - 1, -1, -1);を計算する代わりに、ここで使用しました。それは同じくらい効率的ですが、はるかに読みやすいです。このreversed()関数は反復子を返し、逆数列を非常に効率的に処理します。Python 2 では、次のようにして同じことができますxrange()

for i in reversed(xrange(NumElements)):

デモ:

>>> A = [1, 2, 0, 4, 5, 0]
>>> B = [2, 4, 0, 10, 9, 0]
>>> C = [5, 3, 0, 10, 8, 0]
>>> D = [10, 3, 0, 1, 34, 0]
>>> for i in reversed(range(NumElements)):
...     if not A[i]:
...         del A[i], B[i], C[i], D[i]
... 
>>> A, B, C, D
([1, 2, 4, 5], [2, 4, 10, 9], [5, 3, 10, 8], [10, 3, 1, 34])
于 2013-07-19T10:20:04.690 に答える
2

反対側から作業するだけです!

for n in range(NumElements-1,-1,-1):
    if A[n]==0:
       A.pop(n)
       B.pop(n)
       C.pop(n)
       D.pop(n)
于 2013-07-19T10:14:47.973 に答える
2

私はあなたがこのようなsmthを行うことができると思います. それが十分にPythonicであるかどうかはわかりません。

A = [1, 2, 4, 0]
B = [6, 0, 4, 3, 9]
C = [12, 5, 32, 0, 90]

for row in [A, B, C]:
    for i, v in enumerate(row):
        if v == 0: del row[i]

または、ゼロのインデックスがすべてのリストで等しいことが確実な場合:

for i in range(len(A) - 1, -1, -1):
    if A[i] == 0:
        for row in [A, B, C]:
             del row[i]   
于 2013-07-19T10:13:09.967 に答える
1

これはおそらくハックですが、シンプルで機能します

>>> a = [1,2,3]
>>> b = [1,10,99]
>>> c = [1,87,22]
>>> d = []
>>> d.extend([a,b,c])
>>> to_remove = 1
>>> [i.remove(to_remove) for i in d]
>>> d
[[2, 3], [10, 99], [87, 22]]

これにより、最初のゼロだけでなく to_remove としてマークされたすべての要素が削除されることに注意してください。すべてのゼロを削除したいと言っているので、これで問題ないと思います。

于 2013-07-19T10:23:58.323 に答える
1

Python でアクセスする他の回答リストを見てください。リストをウォークスルーAし、一時リストに 0 のインデックスを保存してから、それらをポップできます。

于 2013-07-19T10:17:45.930 に答える