daiyue
daiyue

Reputation: 7448

python set literal doesn't work with list to create a set

I am trying to use a set literal {} to create a set from a list,

fields = ['field1', 'field2', 'field3', 'field4']
{fields}

TypeError: unhashable type: 'list'

had to use set(fields) to create a set,

{'field1', 'field2', 'field3', 'field4'}

I am wondering what is the reason behind this behavior.

Upvotes: 1

Views: 2073

Answers (2)

skovorodkin
skovorodkin

Reputation: 10274

With {fields} you're trying to make a new set with fields as an element, but list is not hashable, so Python complaints.

set works another way, it expects iterables:

>>> set(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> set('field1')
set(['e', 'd', 'f', 'i', 'l', '1'])

You can create a new set of fields values this way:

>>> fields = ['field1', 'field2', 'field3', 'field4', 'field1']
>>> {*fields}
{'field1', 'field3', 'field4', 'field2'}

Note that you can't create an empty set with {} (that gives you a dict), you have to rely on set() in that cases.

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1121486

Literals are not used to convert; the following won't convert a set to a list either:

aset = {'foo', 'bar'}
alist_from_aset = [aset]

That'd create a list with one element, the set. Your attempt tells Python to create a set with one element, but sets only take hashable objects, and a list is not such an object.

In recent Python 3 releases, you can use iterable unpacking to expand values into separate elements:

{*fields}

That unpacks all the values from a variable into separate values for a set literal:

>>> fields = ['field1', 'field2', 'field3', 'field4']
>>> {*fields}
{'field2', 'field3', 'field1', 'field4'}

See PEP 448 -- Additional Unpacking Generalizations; it's new in Python 3.5.

Upvotes: 1

Related Questions