ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Mon, 22 Aug 2022 11:02:05 +0200Subsets() with same element multiple times?https://ask.sagemath.org/question/63717/subsets-with-same-element-multiple-times/Essentially, I want to use:
ListA = [1,2,3]
S = some_function(ListA, 2)
list(S)
And receive in return
[[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]
Theoretically, `some_function()` ought to be `Subsets()` with some options, but that doesn't seem available. Is there a good way to do this other than a multiple for loop? You can work around how `Subsets()` works with:
ListB = []
for i in ListA:
for j in ListA:
A = sorted([i,j])
if A not in ListB:
ListB.append(A)
sorted(ListB)
But that gets tedious (and probably time-consuming) when you want 6-element subsets--and extra annoying if you want to be able to change the length with a variable. It seems like this ought to be an included functionality; what `some_function()` am I missing?Mon, 22 Aug 2022 02:47:49 +0200https://ask.sagemath.org/question/63717/subsets-with-same-element-multiple-times/Answer by John Palmieri for <p>Essentially, I want to use:</p>
<pre><code>ListA = [1,2,3]
S = some_function(ListA, 2)
list(S)
</code></pre>
<p>And receive in return</p>
<pre><code>[[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]
</code></pre>
<p>Theoretically, <code>some_function()</code> ought to be <code>Subsets()</code> with some options, but that doesn't seem available. Is there a good way to do this other than a multiple for loop? You can work around how <code>Subsets()</code> works with:</p>
<pre><code>ListB = []
for i in ListA:
for j in ListA:
A = sorted([i,j])
if A not in ListB:
ListB.append(A)
sorted(ListB)
</code></pre>
<p>But that gets tedious (and probably time-consuming) when you want 6-element subsets--and extra annoying if you want to be able to change the length with a variable. It seems like this ought to be an included functionality; what <code>some_function()</code> am I missing?</p>
https://ask.sagemath.org/question/63717/subsets-with-same-element-multiple-times/?answer=63718#post-id-63718Python's [itertools](https://docs.python.org/3/library/itertools.html) module has lots of useful functions, including:
sage: import itertools
sage: ListA = [1,2,3]
sage: S = itertools.combinations_with_replacement(ListA, 2)
sage: list(S)
[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
Edit: If you want to use Sage-specific code, you can use [Combinations](https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/combination.html#sage.combinat.combination.Combinations). This will return duplicates only if they appear in the original list, so you can use `ListA * n` to get `n` copies of your list, and then choose combinations from that:
sage: S = Combinations(ListA * 2, 2)
sage: list(S)
[[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3]]
The `itertools` versions seem to be faster, in my limited testing.Mon, 22 Aug 2022 04:21:29 +0200https://ask.sagemath.org/question/63717/subsets-with-same-element-multiple-times/?answer=63718#post-id-63718Answer by Emmanuel Charpentier for <p>Essentially, I want to use:</p>
<pre><code>ListA = [1,2,3]
S = some_function(ListA, 2)
list(S)
</code></pre>
<p>And receive in return</p>
<pre><code>[[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]
</code></pre>
<p>Theoretically, <code>some_function()</code> ought to be <code>Subsets()</code> with some options, but that doesn't seem available. Is there a good way to do this other than a multiple for loop? You can work around how <code>Subsets()</code> works with:</p>
<pre><code>ListB = []
for i in ListA:
for j in ListA:
A = sorted([i,j])
if A not in ListB:
ListB.append(A)
sorted(ListB)
</code></pre>
<p>But that gets tedious (and probably time-consuming) when you want 6-element subsets--and extra annoying if you want to be able to change the length with a variable. It seems like this ought to be an included functionality; what <code>some_function()</code> am I missing?</p>
https://ask.sagemath.org/question/63717/subsets-with-same-element-multiple-times/?answer=63719#post-id-63719Well... Let's try to be lazy, and reuse work already done :
sage: subsets?
Docstring:
Iterator over the *list* of all subsets of the iterable X, in no
particular order. Each list appears exactly once, up to order.
INPUT:
* "X" - an iterable
OUTPUT: iterator of lists
So, what's wrong with :
sage: [u for u in subsets(ListA) if len(u) == 2]
[[1, 2], [1, 3], [2, 3]]
Of course, the `subsets` operator will generate all subsets of `ListA`. It might be interesting to write a specialized generator...
OTOH, someone already did the work (and probably better than I can do) :
sage: Subsets?
Docstring:
Return the combinatorial class of the subsets of the finite set
"s". The set can be given as a list, Set or any iterable
convertible to a set. Alternatively, a non-negative integer n can
be provided in place of "s"; in this case, the result is the
combinatorial class of the subsets of the set \{1,2,...,n\} (i.e.
of the Sage "range(1,n+1)").
A second optional parameter "k" can be given. In this case,
"Subsets" returns the combinatorial class of subsets of "s" of size
"k".
Therefore :
sage: list(Subsets(ListA, 2))
[{1, 2}, {1, 3}, {2, 3}]
Beware : the returned elements are `Set`s (and *not* `set`s). If you insist on lists :
sage: list(map(list, Subsets(ListA, 2)))
[[1, 2], [1, 3], [2, 3]]
HTH,Mon, 22 Aug 2022 11:02:05 +0200https://ask.sagemath.org/question/63717/subsets-with-same-element-multiple-times/?answer=63719#post-id-63719