# For cycles over n-uples

Is it possible to run a for cyle over an n-uple? I give an example with a code that doesn't work as intended: I want to write, for A=[1,2] B=[3,4], something like

  for a,b in A,B:
print(a,b)


and obtain the following

    1,3
1,4
1,5
1,6


I know in this case I could use

 for a in A:
for b in B:
print(a,b)


but in the code I'm writing this is not ideal, basically beacuse I want to do stuff with each of the vectors in the following way

c=[]
A=[[],...[]]
n=len(A)
for x in range(n):
for a in A[x]:
f=function
c.append(f(a))
do stuff with c, reset c to [] in order to repete with different elements


and in this case is harder to have c made the way I want it to be made.

I hope what I mean is clear

EDIT: To be more precise what I have is a set C[[C1], [Cn]] where n depends on the imput and the CI are themself sets.

I want to build (and check a given property) vectors of the type [c1, f1(c1), f1^2(c1),...f1^(e1)(c1),.....fn^(en)(cn)] for ci in CI

Trying to do it in the "traditional way" has the problem of storing the half built vectors. Let's suppose I've built the vector until [c1, f1(c1), f1^2(c1),...f1^(e1)(c1),.....f(n-1)^(e(n-1))(c(n-1))] now I can add the last bunch of components and check if the property is satisfied, but if I want to check the same with a different final bunch (corresponding to a different cn) I have to have stored [c1, f1(c1), f1^2(c1),...f1^(e1)(c1),.....f(n-1)^(e(n-1))(c(n-1))], go back to it and retry.

On the other side if we take a more "mathematical theoretic" approach I don't have this problem where for "mathematical approach" I mean taking (c1,...c_n) in C1 X .... X CN and then just build the final vector from this.

edit retag close merge delete

I hope what I mean is clear

Nope, sorry.

You may try AllRes=[do_stuff(u, v) for v in B for u in A] ; this would gather in a list the results of dostuff(u, v) for all combinations of the elements of A and B. (In contrast, [do_stuff(*v) for v in zip(A, B)] would pick pairs of arguments in A and B in parallel...).

I tried editing the question with more details, I hope this helps clarify my problem

Sort by » oldest newest most voted

To create a list [c1, f1(c1), f1^2(c1),...f1^(e1)(c1),.....fn^(en)(cn)] one can use itertools.accumulate() and itertools.chain.from_iterable() like:

import itertools

c = [2,3,4]
e = [5,4,3]
f = [lambda x: x^2, lambda x: 2*x, lambda x: x+100]
list( itertools.chain.from_iterable( itertools.accumulate(range(ei), func=lambda x,_: fi(x), initial=ci) for ci,ei,fi in zip(c,e,f) ))


The above code iteratively applies given functions fi ei times to ci, where fi, ei, ci are concurrently running through the lists [x^2, 2*x, x+100], [5,4,3] and [2,3,4] respectively, and produces the list:

[2, 4, 16, 256, 65536, 4294967296, 3, 6, 12, 24, 48, 4, 104, 204, 304].

more

It gives me the following error "accumulate() takes at most 2 arguments (3 given)" though

Which version of Sage you're using? You can run the code at sagecell to see how it supposed to work.

Which version of Python your Sage is using? I've just tested the code in Sage 9.2 console with Python 3.8.5 - it works fine there.

The function cartesian_product might answer the question.

sage: A = [1, 2]
sage: B = [3, 4]
sage: for a, b in cartesian_product([A, B]):
....:     print(a, b)
....:
1 3
1 4
2 3
2 4


Or look into Python's itertools module as Max Alekseyev suggests.

more