# Sets depending on a variable

I'm working on an algorithm that takes as impit a set and works accordingly to the set cardinality. In it I would like to define several sets with different properties in a way similar to this

For n in len(S) : Kn=stuff

However we all know the above will create a single set called Kn and work on it whilst I would like to have a set for each n, how can I do it?

This sets will be the base for several other sub algorithm so I need them to extually be defined, it's not enough to have them exist inside a given cycle as I think I should be able to do

edit retag close merge delete

Sort by » oldest newest most voted

First, for n in len(S) won't work, because len(S) is an integer:

TypeError: 'int' object is not iterable

Instead you could either do for n in S (if you want to access the elements of S) or for n in enumerate(S) if you want to count the elements — in this case n will actually range through pairs (i, elt) where i is an integer and elt is an element of S.

Next, to create an object for each element of S, you can use list comprehension:

sage: [i for i in S]  # or [(stuff depending on i)  for i in S]
['b', 'a', 'c']
sage: [i for i in enumerate(S)]  # or ...
[(0, 'b'), (1, 'a'), (2, 'c')]

Edit: you can also do this without list comprehension:

K = []
for i in S:
(create stuff)
K.append(stuff)

Then K will be a list with one entry for each element of S.

more

This looks nice for solving some kind of problem but it's not what I'm looking for I want to create a set for each element though, not an object. It may even be empty but I need to have it and being able to recall it just by knowing the element it comes form. The point is that I need to write stuff like

for a in range(len(S)):
Ka=[set with certain properties depending on the given element of S]

So that later I can go

for b in Ka:
do stuff
( 2021-02-19 21:15:22 +0200 )edit

Does my edit help?

( 2021-02-19 22:01:24 +0200 )edit

It did, it made me realize that I can append sets to sets

( 2021-02-20 14:16:45 +0200 )edit

At the end I chose to do it in the following way

K=[]
for a in range(len(S)):
J=[]
J.append(a^2+a)                                  #do what I need to do on the set J, this is a trivial example
K.append(J)
more

Unless you have a very specific reason to have each of your sets designated by a unique global symbol, the same effect can be achieved by storing your sets in a list. E. g. :

sage: K=[GF(u) for u in (2..100) if u.is_prime()]

K is now a list of all finite fields of size less than or equal to 100 (and set(K) is the set of such fields). The filtering can be done on the set itself rather u. For example, the same list can be obtained by :

[v for v in [Integers(u) for u in (2..100)] if v.is_field()]

As pointed out, you can work on such sets by using K[j] to denote them. Here $j$ would denote the $j$th finite field, not the finite field of size $j$, which may not exist (e. g. one would have K[5] being $\mathbf{F}_{13}$).

You may also store them in a dictionary whose keys are their sizes :

sage: D={u:GF(u) for u in (2..100) if u.is_prime()}

D's elements are accessed by their size, not by their rank in the list :

sage: D.keys()
dict_keys([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97])
sage: D[13]
Finite Field of size 13

If you still need a unique, distinct symbol to denote each of them, lookup sage.misc.misc.inject_variable?. But I fail to see the point...

more