# Regarding remove() function

I want to remove all symmetric matrices from the list of all possible 0,1 matrices of (say) 2nd order. When I run this code, not all symmetric matrices are removed. Where am I wrong?

        T=Tuples((0,1),4)
W=[matrix(2,2,v) for v in T]
[W.remove(s) for s in W if s.is_symmetric() is true]
show(W)

edit retag close merge delete

Sort by » oldest newest most voted Single-line solution:

W = [M for v in Tuples((0,1),4) if not (M:=Matrix(2,2,v)).is_symmetric()]

more

1

It's slightly faster in this case to not construct the matrix unless necessary: W = [Matrix(2,2,v) for v in Tuples((0,1),4) if v != v]. This approach is of course more awkward when dealing with larger matrices.

1

And this is slightly faster: [Matrix(2,2,v) for v in [v for v in Tuples((0,1),4) if v != v]]: construct the appropriate list of tuples first and then convert to matrices. Maybe a bad idea if the list of tuples is going to be long. (I don't know why this should be any faster.)

Thanks John. Yes, your idea is good. Yes, for higher orders this is going to be complicated.

@John: Then one can simply do [Matrix(2,2,v[:2]+[1-v,v]) for v in Tuples((0,1),3)].

In your code W defines the range of the loop but changes inside.

It can be improved as follows:

T=Tuples((0,1),4)
W=[matrix(2,2,v) for v in T]
V=W.copy()
[V.remove(s) for s in W if s.is_symmetric()]
V

[
[0 1]  [1 1]  [0 0]  [1 0]  [0 1]  [1 1]  [0 0]  [1 0]
[0 0], [0 0], [1 0], [1 0], [0 1], [0 1], [1 1], [1 1]
]


but it is better not to construct to many matrices:

import itertools
def  f():
f1=lambda x:matrix(2,2,x)
f2=lambda v:v!=v
T=(item for item in itertools.product([0,1], repeat=4))
return list(map(f1,filter(f2,T)))
f()

[
[0 0]  [0 0]  [0 1]  [0 1]  [1 0]  [1 0]  [1 1]  [1 1]
[1 0], [1 1], [0 0], [0 1], [1 0], [1 1], [0 0], [0 1]
]

timeit('f()')

625 loops, best of 3: 40.7 μs per loop


In intel python, replacing matrix by numpy.array one can obtain two times faster code

more

1

Why not use list comprehension right away?

[m for m in mm if not m.is_symmetric()]`