aniketd
aniketd

Reputation: 405

python set.remove behavior and other builtins

In Python 2.7.x

In [21]: s = set([-1, -1, -1, 0, -1, 0, 0, 0, 0]).remove(-1)

In [22]: type(s)
Out[22]: NoneType

and

In [23]: s = set([-1, -1, -1, 0, -1, 0, 0, 0, 0])

In [24]: type(s)
Out[24]: set

In [25]: s.remove(-1)

In [26]: type(s)
Out[26]: set

In [27]: s
Out[27]: set([0])

Why does function chaining not work as expected in the above example?

Upvotes: 2

Views: 96

Answers (3)

thefourtheye
thefourtheye

Reputation: 239573

s = set([-1, -1, -1, 0, -1, 0, 0, 0, 0])

remove returns None. You can confirm that by printing the type of the return value from remove like this

print type(s.remove(-1))

you will get

<type 'NoneType'>

So, basically you are setting None to s.

Upvotes: 2

mgilson
mgilson

Reputation: 310049

generally, with python builtins, if the method modifies the object, it returns None to make it absolutely explicit that the object was modified in place. In this case, set.remove modifies the set in place, so by convention, it should return None.

You'll see the same behavior with list.remove or list.append or set.add for example.

This comes as a shock to people coming from different languages where it is common for a method to mutate the object and (effectively) to return self. It's convenient in that it allows methods to be chained nicely... But, the core python dev's have chosen a different path because they believe (and I agree) that in the long run, it leads to cleaner more obvious code. I would advise you to use python's convention in your own python code (but of course, you're free to disregard that advice completely).

Upvotes: 6

TerryA
TerryA

Reputation: 60004

set.remove() does not return a set with the removed items, it removes them in place. As it does this, the function will return None. So technically you are doing s = None in your first example.

Upvotes: 4

Related Questions