# Modify a set and removing elements

I'm trying to modify a set but I'm having some problems doing so (I hope the code her è behaves the same as the one I have at home, at the moment I don't have access to the algorithms creating the specific set)

N=[[(0,0,1)],[(0,1,0)],[(0,1,1)],[(1,0,0)],[(1,0,1)],[(0,1,0)],[(1,1,1)]]

For a in N:
N.remove(a)
a.append(1)
N.append(a)


This creates problems given how it doesn't remove all the elements and doesn't modify all of them

I kinda solved by introducing another set as

V=copy(N)

For a in N:
V.remove(a)
a.append(1)
V.append(a)


Now V behaves well, so I have two questions (plus a bonus one) :

Why does the first method create problems?

Using the second method I would like (the target algorithm does this for a set of a so I need the result to pass through the same process given that I need to add other elements to every eleemnt/set) at the end to set N as equal to V but neither using N=V, N=copy(V) nor N=[] and then appending all the elemts seems to work.

Is there a better way to do what I want to do? So a better way to take elements of a set and obatain another set whose elements are the starting ones modified by adding elements from another set? E. G. starting from A=[[1], [2]] , B=[a, b] obtain A=[[1,a], [1,b], [2,a],[2,b]]

edit retag close merge delete

Sort by » oldest newest most voted

Here is an easy way to accomplish what you want:

sage: A = [[1], [2]]
sage: B = ['a', 'b']
sage: [[x + [y] for x in A] for y in B]
[[[1, 'a'], [2, 'a']], [[1, 'b'], [2, 'b']]]


Or if you like:

C = []
for x in A:
for y in B:
C.append(x+[y])


I think that the problem with your original code is that you are looping over a list while also modifying that list, which is why working with a copy helps. Note also that code like a.append(1) will change the original list a, and that can be confusing.

for x in A:
x.append(2)


modifies each list in A, while

for x in A:
x + [2]


leaves A unchanged.

Edit: this looks like a job for itertools: https://docs.python.org/3/library/ite.... Create multiple lists A = [1, 2], B = ['a', 'b'], C = ['o', 'p'] and do

from itertools import product
product(A, B, C)


or to get something more explicit:

list(product(A, B, C))


(The product function gives the Cartesian product of the inputs.) If you don't want multiple lists, create a single list C = [[1, 2], ['a', 'b'], ['o', 'p']] and then do product(*C). (Or if you have your two lists A and B as in the comments, you can replace A with A = [x[0] for x in A] and do C = A + B. It's just list manipulation at this point.)

more

The fact is that I want to change the original set, this because I need to add elements from B, then from C and so on and end up with a set that is just the set of all such lists. The rest is exactly what I needed.

( 2021-02-22 20:59:28 +0200 )edit

So what about the last question? How can I set A equal to the resulting "fused" set so that something like this (for A=[[1],[2]], B=[[a,b],[o,p]])

C=[]
for x in A:
for n in range(2):
for y in B[n]:
C.append(x+[y])


ends up gving me A=[[1,a,o],[1,a,p],[1,b,o],[1,b,p],[2,a,o],[2,a,p],[2,b,o],[2,b,p]]?

( 2021-02-22 21:12:02 +0200 )edit

I came up with this but for some reason it takes ages to run

A=[[1],[2]]
B=[[5,6],[8,9]]
C=[]
def Fus(N,M):
l=len(M)
for n in range(l+1):
E.append([])
E[0]=N
for n in range(l):
for x in E[n]:
for y in M[n]:
E[n+1].append(x+[y])
C=E[l]

( 2021-02-22 22:22:37 +0200 )edit

See my edit. Looks like you want the Cartesian product of [1, 2], ['a', 'b'], and ['o', 'p'].

( 2021-02-22 23:06:19 +0200 )edit

I fee like it's not ideal in my case, the problem is that at the end I want my set, starting from A=[[a_1,...a_n],[b_1,...b_l],[c_1, ....c_m]]

to be made of elements like

[a_i, f(a_i), f^2(a_i),....f^k(a_i), b_j,....g^h(b_j),c_y,.....h^r(c_y)]

so the "simple" cartesian product (that it's indeed a nice solution to the problem you though I had) may not be enough, also beacuse I don't know how many sets are in my set (I mean it changes based on the input)

( 2021-02-23 16:19:23 +0200 )edit