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,980
  • 23
  • 69
  • 137

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
  • 114,268
  • 16
  • 167
  • 218
  • 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
  • 5,026
  • 24
  • 37
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
  • 88,713
  • 10
  • 131
  • 172