1

In a tutorial I've read that sets can since Python 2.6 be defined like this:

a_set = {"Members", "of", "set"}

But let's say I want to achieve a_set = set("Letters") with that notation. a_set = {"Letters"} does not render the same output when printed:

>>> set1 = set("Letters")
>>> set2 = {"Letters"}
>>> print(set1, set2)
{'L', 'r', 't', 'e', 's'} {'Letters'}

Is the tutorial wrong? What is going on here? If set2 is not a set, what is it?

Sahand
  • 7,038
  • 19
  • 61
  • 121

3 Answers3

3

The first variable set1 creates a new set from the sequence of letters in the single string "Letters".

The second variable set2 creats a set with a single str object. It does not iterate over the individual letters to make a set.

Cory Kramer
  • 107,498
  • 14
  • 145
  • 201
  • Thanks. Is it possible to achieve `set1`by using the `{}`-notation? – Sahand Aug 17 '17 at 19:04
  • @Sandi Not really. unless yous want to hack the CPython source code. Is there a reason you can't use `set`? – Christian Dean Aug 17 '17 at 19:05
  • `{*'letters'}` works on Python 3.6. Didn't try it on 2.x though. – ayhan Aug 17 '17 at 19:05
  • No reason, I'm just curious. Thanks ayhan! What's the logic behind that working? What does asterisk no? – Sahand Aug 17 '17 at 19:06
  • 1
    @Sandi It unpacks an iterable. Assume you have a list `a = ['x', 'y']` Normally, if you call a function with `func(a)` the list is passed as the input. But if you do `func(*a)` it works like you did `func('x', 'y')` [Here](https://stackoverflow.com/questions/400739/what-does-asterisk-mean-in-python) are more details. – ayhan Aug 17 '17 at 19:11
2

Because in the first set you're passing an iterable. Pass it in a list like this and it will give you what you want.

In [148]: set(["Letters"])
Out[148]: {'Letters'}
Cory Madden
  • 4,648
  • 21
  • 36
2

You are fundamentally confusing literal notation with a constructor function. The constructor functions for all the built-in containers take iterables and populate the container with the elements of the iterable. A container literal does not work this way, and isn't designed to work this way. Note, this is how it works with every built-in container type that supports literal notation:

>>> list('letters')
['l', 'e', 't', 't', 'e', 'r', 's']
>>> ['letters']
['letters']
>>>

So this shouldn't be surprising.

juanpa.arrivillaga
  • 77,035
  • 9
  • 115
  • 152