Ask Your Question
0

one element is missing while using Set( generator ) [closed]

asked 2022-05-01 20:26:51 +0200

Max Alekseyev gravatar image

updated 2022-05-01 20:42:26 +0200

In the code:

import itertools
Q = [[factor(5),factor(13)],[factor(9),factor(7),factor(13)]]
print( sorted( Set( [lcm(*qq) for qq in itertools.product(*Q)] ) ) )
print( sorted( Set( (lcm(*qq) for qq in itertools.product(*Q)) ) ) )

first print produces the expected result:

[13, 5 * 7, 3^2 * 5, 5 * 13, 7 * 13, 3^2 * 13]

while second print produces a list with one element (3^2 * 5) missing:

[13, 5 * 7, 5 * 13, 7 * 13, 3^2 * 13]

Is this a bug?


ADDED. More weirdness - the following code

Q = [[factor(3), factor(9)], [factor(9), factor(7)]]
print( Set( [lcm(*qq) for qq in itertools.product(*Q)] ) )

produces a set with two equal elements:

Set of elements of [3^2, 3 * 7, 3^2, 3^2 * 7]

It seems that these issues are related to the fact that Factorization objects are not hashable, but why then does Set allow to create sets of them with all kinds of side effects?

edit retag flag offensive reopen merge delete

Closed for the following reason question is not relevant or outdated by Max Alekseyev
close date 2024-02-19 18:39:24.561147

Comments

1

and Set is not working correctly with iterators

FrédéricC gravatar imageFrédéricC ( 2022-05-01 21:28:06 +0200 )edit
1

I can't reproduce the first issue: I get the same answer — the first one — when I repeat the print command. What version of Sage are you using? I agree with the final question: Set allows nonhashable objects, and it doesn't look very good, for example Set([[3,4], [3,4]]).

John Palmieri gravatar imageJohn Palmieri ( 2022-05-01 23:09:01 +0200 )edit

I use Sage 9.5 The first issue can be also seen in SageMathCell: https://sagecell.sagemath.org/?q=ainesk

Max Alekseyev gravatar imageMax Alekseyev ( 2022-05-02 00:00:07 +0200 )edit

Maybe it's been fixed in the 9.6 prerelease.

John Palmieri gravatar imageJohn Palmieri ( 2022-05-02 06:34:59 +0200 )edit

I can reproduce with 9.6.rc3 on macOS 12.3.1

David Coudert gravatar imageDavid Coudert ( 2022-05-02 08:35:56 +0200 )edit

1 Answer

Sort by » oldest newest most voted
0

answered 2022-05-02 21:34:12 +0200

The problem is this block in the code for Set:

try:
    X = frozenset(X)
except TypeError:
    return Set_object(X)
else:
    return Set_object_enumerated(X)

When the entries of X are not hashable, frozenset(X) fails, but it still accesses X. If X is a generator, you lose the first entry of X this way. This change in sage.set.set might fix it:

diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py
index 96e3b2ad7a..ff133a315e 100644
--- a/src/sage/sets/set.py
+++ b/src/sage/sets/set.py
@@ -198,11 +198,12 @@ def Set(X=None):
         raise TypeError("Element has no defined underlying set")

     try:
-        X = frozenset(X)
+        Y = list(X)
+        Y = frozenset(Y)
     except TypeError:
-        return Set_object(X)
+        return Set_object(Y)
     else:
-        return Set_object_enumerated(X)
+        return Set_object_enumerated(Y)


 class Set_base():
edit flag offensive delete link more

Comments

Would there be an unneeded overhead for hashavle elements? Given various side effects, I'd rather disable Sets for unhashable elements.

Max Alekseyev gravatar imageMax Alekseyev ( 2022-05-02 21:40:50 +0200 )edit

After the initial construction (this try ... except block), a Set with hashable elements will be an instance of a different Python class than one with unhashable elements, so I hope there is no overhead.

John Palmieri gravatar imageJohn Palmieri ( 2022-05-02 21:52:32 +0200 )edit

Creating a list before creating a frozenset brings an overhead. Think about an object with millions of elements.

Max Alekseyev gravatar imageMax Alekseyev ( 2022-05-02 22:00:15 +0200 )edit

As far as I can tell, there is no way to access an iterator without modifying it, and frozenset(X) accesses it. I don't know another way to keep the current functionality and also to fix this bug. Users can explicitly import and call Set_object_enumerated on frozenset(X) if they know that will work.

John Palmieri gravatar imageJohn Palmieri ( 2022-05-02 23:37:22 +0200 )edit

Should I open a ticket for this issue?

Max Alekseyev gravatar imageMax Alekseyev ( 2022-05-24 04:46:43 +0200 )edit

Question Tools

1 follower

Stats

Asked: 2022-05-01 20:26:51 +0200

Seen: 147 times

Last updated: May 02 '22