Random result from creating a comprehension Set out of a List

Hi, I am a beginner in Python programming. I am trying to learn the difference between List and Set, so I created an example using set comprehension to create a Set Z from a list MyList. The set Z will contain boolean values (True/False) based on whether each number in MyList is even or not.

The first example is using set comprehension. On the second example, I used For-Loop to emulate the set comprehension. The results are identical if I add Boolean (True/False) to the set. But when I add String (ā€˜Trueā€™ / ā€˜Falseā€™), I have an opposite result.

The expected result is: {False, True}

My result is correct if I add Boolean Value True or False to the set.
actual result = {False,True}

 SetZ.add(True)

However, if I use String Value ā€˜Trueā€™ or ā€˜False,ā€™ I end up with the actual result {ā€˜Trueā€™ ā€˜Falseā€™}.

I am unclear why the order is different whether you use Boolean or String.

 SetZ.add('True')

Below is my example:

# Uset set comprehension
MyList = [4, 3, 5, 6, 5, 5, 4, 4, 8]
ExpectedSet = {True if n % 2 == 0 else False for n in MyList}
print("expected answer:", ExpectedSet, "\n")

# Use for loop to emulate set comprehension
SetZ = set()  # Initialize an empty set
for n in MyList:
    condition = n % 2 == 0

    if condition:
        SetZ.add(True)
        print(f"n:{n}=> z.add({condition}), {SetZ}")
    else:
        SetZ.add(False)
        print(f"n:{n}=> z.add({condition}), {SetZ}")

print("Actual SetZ:", SetZ)

Output using Boolean

expected answer: {False, True} 

n:4=> z.add(True), {True}
n:3=> z.add(False), {False, True}
n:5=> z.add(False), {False, True}
n:6=> z.add(True), {False, True}
n:5=> z.add(False), {False, True}
n:5=> z.add(False), {False, True}
n:4=> z.add(True), {False, True}
n:4=> z.add(True), {False, True}
n:8=> z.add(True), {False, True}
Actual SetZ: {False, True}

Output using String Value

expected answer: {False, True} 

Result using String Value 

n:4=> z.add(True), {'True'}
n:3=> z.add(False), {'True', 'False'}
n:5=> z.add(False), {'True', 'False'}
n:6=> z.add(True), {'True', 'False'}
n:5=> z.add(False), {'True', 'False'}
n:5=> z.add(False), {'True', 'False'}
n:4=> z.add(True), {'True', 'False'}
n:4=> z.add(True), {'True', 'False'}
n:8=> z.add(True), {'True', 'False'}
Actual SetZ: {'True', 'False'}

What am I missing?

You first: I donā€™t understand - why do you think it should be the same order?

The string 'True' and the boolean value True have nothing to do with each other, and similarly for 'False' and False.

1 Like

I thought the order of adding an item to the set should be the same regardless of the boolean or string to the Set. I know that Set is an unordered list with unique items. My question is why the boolean False was added to the front of the Set when the ā€œFalseā€ was append.

From the MyList, you can see when n=3, the logic should add False to the Set like this {True, False}, but instead, it did this {False, True}. It could be that I donā€™t have a good understanding of how Python works.

Sets, by definition, do not have any concept of order. Whatever youā€™re seeing is a mere artifact of implementation, and might change at any time. All you can be sure of is that the set will correctly track presence and absence.

Notably, two sets will be considered equal if they contain the same elements but in a different order. Or even if they contain elements that compare equal:

>>> {True, False} == {0, 1}
True

But the order is never going to be relevant to anything.

1 Like

Thank you. What you are saying {False, True} or {True, False} or {ā€˜Trueā€™ or 'False} are all correct answers. I am trying to get certified in Python, so I want to have a solid understanding that we could have multiple correct answers.

Right: this tells you that, when you add two things to the set, the set may or may not put them in the same order that you inserted them, according to its own logic. That logic can depend on many things, such as the total number of elements, the actual values, the actual types, and possibly other things.

Because ā€˜when the ā€œFalseā€ was appendedā€™, ā€œthe Falseā€ was not added at all - because the string 'False' and the boolean value False have nothing to do with each other. Therefore, what happens when you add False to a set - regardless of what values are already in the set - tells you nothing about what would happen if you had added 'False' instead.

In your code, either way, only two values can get added. Once both possibilities are added, the set is fixed - every other attempt to add an element will do nothing, because the element to add is already there. But those first two times, the order depends on many things. And there is no reason why any given value should tell you anything all about ā€œwhereā€ any other given value should go, or how they get ā€œorderedā€. Because, in concept, they arenā€™t ordered at all. The order is only a consequence of the fact that everything has to go somewhere in order for it to be remembered.

1 Like

Thank you so much. If I see something like that in an exam, I can safely pick the answer {False, True} or {True, False} as long the set contains only two items T or F. Your explanation helped.