Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

del and sets proposal

0 views
Skip to first unread message

Larry Bates

unread,
Oct 2, 2008, 6:20:05 PM10/2/08
to
You can do the following:

a = [1,2,3,4,5]
del a[0]

and

a = {1:'1', 2: '2', 3: '3', 4:'4', 5:'5'}
del a[1]

why doesn't it work the same for sets (particularly since sets are based on a
dictionary)?

a = set([1,2,3,4,5])
del a[1]

Yes I know that sets have a remove method (like lists), but since dictionaries
don't have a remove method, shouldn't sets behave like more like dictionaries
and less like lists? IMHO del for sets is quite intuitive. I guess it is too
late to change now.

-Larry

Chris Rebert

unread,
Oct 2, 2008, 6:39:55 PM10/2/08
to Larry Bates, pytho...@python.org
On Thu, Oct 2, 2008 at 3:20 PM, Larry Bates <larry...@vitalesafe.com> wrote:
> You can do the following:
>
> a = [1,2,3,4,5]
> del a[0]
>
> and
>
> a = {1:'1', 2: '2', 3: '3', 4:'4', 5:'5'}
> del a[1]
>
> why doesn't it work the same for sets (particularly since sets are based on
> a dictionary)?
>
> a = set([1,2,3,4,5])
> del a[1]

Sets don't support subscripting, so if you can't go
'a_set[something]', why would you expect to be able to be able to
'del' such an expression? What would the subscription even mean
without the 'del'? It doesn't make sense and would just be
inconsistent.

>
> Yes I know that sets have a remove method (like lists), but since
> dictionaries don't have a remove method, shouldn't sets behave like more
> like dictionaries and less like lists? IMHO del for sets is quite

No, sets are a datatype unto themselves. They are based on
dictionaries internally (at least in CPython), but that's an
implemention detail to be hidden, not emphasized.

> intuitive. I guess it is too late to change now.

Most likely.

Cheers,
Chris
--
Follow the path of the Iguana...
http://rebertia.com

>
> -Larry
> --
> http://mail.python.org/mailman/listinfo/python-list
>

Jon Clements

unread,
Oct 2, 2008, 7:48:42 PM10/2/08
to

>>> a = set( range(5) )
>>> a[0]

Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
a[0]
TypeError: 'set' object is unindexable

No point it needing to be indexable either.

It's also worth noting that removing an object from a container
(.remove) is different than proposing the object goes to GC (del...)

Have to disagree that del[] on a set makes any sense.

Tired, and it's late, so probably typing rubbish, but felt okay when I
started reading the group :)

Jon.

Marc 'BlackJack' Rintsch

unread,
Oct 2, 2008, 7:55:42 PM10/2/08
to
On Thu, 02 Oct 2008 16:48:42 -0700, Jon Clements wrote:

> It's also worth noting that removing an object from a container
> (.remove) is different than proposing the object goes to GC (del...)

``del`` doesn't propose that the object goes to GC, at least not more
then a `remove()` method does. Just like `remove()` ``del`` only removes
references to objects. Always.

Ciao,
Marc 'BlackJack' Rintsch

bearoph...@lycos.com

unread,
Oct 2, 2008, 7:59:52 PM10/2/08
to
Chris Rebert:

> No, sets are a datatype unto themselves. They are based on
> dictionaries internally (at least in CPython), but that's an
> implemention detail to be hidden, not emphasized.

Later Hettinger has simplified their code, making them use less memory
(and be a little faster too, I think) :-)

Bye,
bearophile

Marc 'BlackJack' Rintsch

unread,
Oct 2, 2008, 8:02:12 PM10/2/08
to
On Thu, 02 Oct 2008 15:39:55 -0700, Chris Rebert wrote:

> On Thu, Oct 2, 2008 at 3:20 PM, Larry Bates <larry...@vitalesafe.com>
> wrote:
>> a = set([1,2,3,4,5])
>> del a[1]
>
> Sets don't support subscripting, so if you can't go 'a_set[something]',
> why would you expect to be able to be able to 'del' such an expression?
> What would the subscription even mean without the 'del'? It doesn't make
> sense and would just be inconsistent.

Then add subscription access too. By aliasing `__getitem__()` to
`__contains__()`. And `__setitem__()` could be implemented to add or
remove objects by assigning truth values. So hypothetically:

>>> a = set([1, 2, 3])
>>> a[1]
True
>>> a[4]
False
>>> a[2] = False
>>> a
set([1, 3])
>>> a[4] = True
>>> a
set([1, 3, 4])
>>> del a[1]
>>> a
set([3, 4])

I wouldn't want that addition to `set`\s but at least it can be
implemented without introducing inconsistencies.

Ciao,
Marc 'BlackJack' Rintsch

Larry Bates

unread,
Oct 2, 2008, 11:27:04 PM10/2/08
to

I believe that the fact that Sets don't support indexing is an implementation
artifact that is due to the FACT that their underlying implementation is based
on dictionaries (a good choice in my opinion). One could just as easily have
implemented (but then they would not have performed so well) Sets as an ordered
list of unique values and have provided indexing capabilities (but I can't quite
think of a use case for such an animal right now).

I didn't mean to imply that del a[1] would delete the first thing in the set,
but rather the item with a value of 1. Just as when we use it on a dictionary:

del a[1]

doesn't mean delete the first dictionary entry but rather delete the entry in
the object with a value of 1, which IMHO would be perfectly logical for a set
(which is why I started this discussion). There is no ambiguity because sets,
like dictionaries, require uniqueness.

Maybe dictionaries should have had a .remove method then things would be more
consistent?

-Larry

George Sakkis

unread,
Oct 3, 2008, 3:30:11 AM10/3/08
to

Funny, I would welcome a change in the opposite direction: drop
completely the "del a[i]" syntax from the language and use an explicit
(non-special) method name, e.g. a.delete(i) or a.remove(i). Having
some functionality exposed through methods and some through function
builtins (e.g. len()) is more than enough; having a third way through
the del statement is unnecessarily perl-ish.

George

Steven D'Aprano

unread,
Oct 3, 2008, 4:29:47 AM10/3/08
to
On Thu, 02 Oct 2008 22:27:04 -0500, Larry Bates wrote:

> Maybe dictionaries should have had a .remove method then things would be
> more consistent?

But why should sets be consistent with dictionaries? There are a few
similarities, but also differences.

Personally, I'd rather see dictionaries grow methods like
symmetric_difference, union, etc. than worry about whether you use del or
remove to remove elements from a set.


--
Steven

Carl Banks

unread,
Oct 3, 2008, 5:09:09 AM10/3/08
to
On Oct 2, 8:02 pm, Marc 'BlackJack' Rintsch <bj_...@gmx.net> wrote:
> On Thu, 02 Oct 2008 15:39:55 -0700, Chris Rebert wrote:
> > On Thu, Oct 2, 2008 at 3:20 PM, Larry Bates <larry.ba...@vitalesafe.com>


If set behaved that way then "del a[1]" wouldn't behave like del
anymore. Normally, "del whatever" means that you can no longer use
"whatever"; in this proposal you can.


Carl Banks

Carl Banks

unread,
Oct 3, 2008, 5:18:53 AM10/3/08
to
On Oct 2, 11:27 pm, Larry Bates <larry.ba...@vitalEsafe.com> wrote:
> I didn't mean to imply that del a[1] would delete the first thing in the set,
> but rather the item with a value of 1.  Just as when we use it on a dictionary:
>
> del a[1]
>
> doesn't mean delete the first dictionary entry but rather delete the entry in
> the object with a value of 1, which IMHO would be perfectly logical for a set
> (which is why I started this discussion).


It's not logical at all. In all current uses of del, the thing that
follows del is a valid expression. With sets, that's not the case.


Carl Banks

Steven D'Aprano

unread,
Oct 3, 2008, 5:29:00 AM10/3/08
to


I think Larry is suggesting that elements of sets should be removed in
the same way that keys of dictionaries are removed:

d = {57: "foo"}
s = set([57])


He's suggesting that del s[57] should work just like del d[57] works.

The fact that sets don't have a __getitem__ method doesn't mean that they
couldn't have a __delitem__ method:

class DelSet(set):
def __delitem__(self, element):
self.remove(element)


>>> s = DelSet([1, 2, 3, 4, 5])
>>> s
DelSet([1, 2, 3, 4, 5])
>>> del s[4]
>>> del s[5]
>>> s
DelSet([1, 2, 3])


--
Steven

bearoph...@lycos.com

unread,
Oct 3, 2008, 6:37:03 AM10/3/08
to
Steven D'Aprano:

> Personally, I'd rather see dictionaries grow methods like
> symmetric_difference, union, etc. than worry about whether you use del or
> remove to remove elements from a set.

I have functions for all those operations, so I think they can be
useful, but in practice I don't use them often. I think it's a matter
of keeping data structures separated in the mind.

Another problem is that with those operations you have to find a way
to manage values too, are they part of the uniqueness, etc? So there
can be different semantics of a single operation, and this may lead to
people that have a wrong image model of the purpose of some of those
methods.

Bye,
bearophile

Marc 'BlackJack' Rintsch

unread,
Oct 3, 2008, 9:59:20 AM10/3/08
to

Then there should be no ``del`` for `collections.defaultdict`:

In [169]: from collections import defaultdict

In [170]: d = defaultdict(int)

In [171]: d[42]
Out[171]: 0

In [172]: del d[42]

In [173]: d[42]
Out[173]: 0

Ciao,
Marc 'BlackJack' Rintsch

Bruno Desthuilliers

unread,
Oct 4, 2008, 12:36:28 PM10/4/08
to
Larry Bates a écrit :

For lists, del a[x] means 'remove item at index x'. For dicts, del a[x]
means 'remove key:value pair which key is x'. In both cases, del a[x] is
meaningful because a[x] is meaningful. Sets are neither ordered nor
indexed, and can't be subscripted. So "del aset[x]" is IMHO as
meaningless as 'aset[x]' is. Using this syntax for an operation which
semantic is the same as alist.remove(x) would be at best inconsistent
and confusing.

Steven D'Aprano

unread,
Oct 4, 2008, 9:05:37 PM10/4/08
to
On Sat, 04 Oct 2008 18:36:28 +0200, Bruno Desthuilliers wrote:

>> Yes I know that sets have a remove method (like lists), but since
>> dictionaries don't have a remove method, shouldn't sets behave like
>> more like dictionaries and less like lists? IMHO del for sets is quite
>> intuitive.
>
> For lists, del a[x] means 'remove item at index x'. For dicts, del a[x]
> means 'remove key:value pair which key is x'. In both cases, del a[x] is
> meaningful because a[x] is meaningful. Sets are neither ordered nor
> indexed, and can't be subscripted. So "del aset[x]" is IMHO as
> meaningless as 'aset[x]' is. Using this syntax for an operation which
> semantic is the same as alist.remove(x) would be at best inconsistent
> and confusing.

Consider the mutable built-in collections set, dict and list, and how
they remove elements:

aset.remove(x)
alist.remove(x)
del adict[x]

Would it really be "confusing" if sets used the same interface as dicts
use? I don't think so. What else could "del aset[x]" mean other than
"delete element x"?

Lists are the odd one out, because del alist[x] is used to remove the
element at position x, rather than removing an element x. But because
sets are unordered, there's no ambiguity between element x and the
element at position x. In that regard, sets are just like dicts, and it
is a perfectly reasonable position to take that hypothetically sets could
use "del aset[x]" instead of "aset.remove(x)".

But on the other hand, if you can write "del aset[x]", why can't you
write "y = aset[x]" or "aset[x] = z"? Neither of these seem useful or
sensible, although at a stretch we could make "y = aset[x]" equivalent to
"y = x in aset".

Although there's no technical reason why sets can't have a __delitem__
method but no __getitem__ and __setitem__ methods, for consistency it
does seem rather unusual.

All this may seem academic, but consider the Bag (Multiset) data type.
With a Bag, you need to have two commands: "remove element x entirely",
and "remove one copy of element x only". To my mind, the natural API for
that is:

del abag[x] # remove element x entirely
abag.remove(x) # remove one copy of element x only

--
Steven

Lawrence D'Oliveiro

unread,
Oct 5, 2008, 5:11:38 AM10/5/08
to
In message <00f80c6a$0$20633$c3e...@news.astraweb.com>, Steven D'Aprano
wrote:

> Would it really be "confusing" if sets used the same interface as dicts
> use? I don't think so. What else could "del aset[x]" mean other than
> "delete element x"?

Yes, but "x" in what sense? In dicts it's a key, in sets, shouldn't it also
be a key and not a value?

Sets have no keys, only values. One might suggest assignment of keys, à la
array indexes, but that means assigning an ordering to the values, whereas
sets are explicitly unordered.

Steven D'Aprano

unread,
Oct 5, 2008, 6:12:39 AM10/5/08
to
On Sun, 05 Oct 2008 22:11:38 +1300, Lawrence D'Oliveiro wrote:

> In message <00f80c6a$0$20633$c3e...@news.astraweb.com>, Steven D'Aprano
> wrote:
>
>> Would it really be "confusing" if sets used the same interface as dicts
>> use? I don't think so. What else could "del aset[x]" mean other than
>> "delete element x"?
>
> Yes, but "x" in what sense?

The only sense possible.

If I wrote aset.remove(x) would you ask "what's x, a key or a value?" No
of course you wouldn't, because the question is nonsense for sets. The
same goes for "x in aset", "aset.add(x)" and any other set method that
takes an element as an argument. Why are you singling out del for this
pretend confusion?


> In dicts it's a key, in sets, shouldn't it
> also be a key and not a value?

That question isn't even meaningful. Sets have elements. The semantics of
set elements is closer to dictionary keys than to dictionary values:

x in adict # is key x in dictionary?
x in aset # is element x in set?

and an early implementation of Python sets used dictionaries, where the
elements where stored as keys, not values. It makes no sense to treat set
elements as if they were analogous to dict values.


> Sets have no keys, only values. One might suggest assignment of keys, à
> la array indexes, but that means assigning an ordering to the values,
> whereas sets are explicitly unordered.

Why on earth should "del aset[x]" imply that sets are ordered? Dicts
aren't ordered. You don't find people going "wibble wibble wibble, I
don't understand del adict[x] because dicts aren't ordered, what could it
mean???"


--
Steven

Bruno Desthuilliers

unread,
Oct 5, 2008, 10:15:41 AM10/5/08
to
Steven D'Aprano a écrit :

> On Sat, 04 Oct 2008 18:36:28 +0200, Bruno Desthuilliers wrote:
>
>>> Yes I know that sets have a remove method (like lists), but since
>>> dictionaries don't have a remove method, shouldn't sets behave like
>>> more like dictionaries and less like lists? IMHO del for sets is quite
>>> intuitive.
>> For lists, del a[x] means 'remove item at index x'. For dicts, del a[x]
>> means 'remove key:value pair which key is x'. In both cases, del a[x] is
>> meaningful because a[x] is meaningful. Sets are neither ordered nor
>> indexed, and can't be subscripted. So "del aset[x]" is IMHO as
>> meaningless as 'aset[x]' is. Using this syntax for an operation which
>> semantic is the same as alist.remove(x) would be at best inconsistent
>> and confusing.
>
> Consider the mutable built-in collections set, dict and list, and how
> they remove elements:
>
> aset.remove(x)
> alist.remove(x)
> del adict[x]

This last one doesn't remove the key,value pair(s) where *the value* is
x, it removes the key,value pair where the *key* is x - which is
semantically very different, just like alist.remove(x) is very different
from del alist[x].

> Would it really be "confusing" if sets used the same interface as dicts
> use? I don't think so.

I do. In both dict.__delitem__ and list.__delitem__, the argument is an
index (whether arbitrary key or positional index), not the value of the
element to remove. wrt/ consistency, i'd rather have dict growing a
remove(value) method with same semantic as list.remove and set.remove
than abuse subscript syntax to duplicate an existing API which has a
very different semantic.

> What else could "del aset[x]" mean

As far as I'm concerned, since sets are not subscriptables, del aset[x]
just can't have any meaning.

> other than
> "delete element x"?

Going this way, 'del adict[x]' should mean 'remove key,value pair(s)
where value is x' and 'del alist[x]' should be an alias for alist.remove(x).


> Lists are the odd one out, because del alist[x] is used to remove the
> element at position x, rather than removing an element x.

Nope. It's perfectly consistent with dicts, where del adict[x] is used
to remove element associated to key x, not to remove element with value
x. Lists and dicts are both indexed collections, list being indexed by
position and dicts by key. sets are not indexed.

(snip remaining - I could only keep on repeating the same thing).

Bruno Desthuilliers

unread,
Oct 5, 2008, 10:22:18 AM10/5/08
to
Steven D'Aprano a écrit :
> On Sun, 05 Oct 2008 22:11:38 +1300, Lawrence D'Oliveiro wrote:
>
>> In message <00f80c6a$0$20633$c3e...@news.astraweb.com>, Steven D'Aprano
>> wrote:
>>
>>> Would it really be "confusing" if sets used the same interface as dicts
>>> use? I don't think so. What else could "del aset[x]" mean other than
>>> "delete element x"?
>> Yes, but "x" in what sense?
>
> The only sense possible.
>
> If I wrote aset.remove(x) would you ask "what's x, a key or a value?" No
> of course you wouldn't, because the question is nonsense for sets.

And also because the semantic of 'remove' is already defined for lists.

> The
> same goes for "x in aset", "aset.add(x)" and any other set method that
> takes an element as an argument. Why are you singling out del for this
> pretend confusion?
>
>
>> In dicts it's a key, in sets, shouldn't it
>> also be a key and not a value?
>
> That question isn't even meaningful. Sets have elements. The semantics of
> set elements is closer to dictionary keys than to dictionary values:
>
> x in adict # is key x in dictionary?

This is a pragmatic design choice - just like the fact that default
iteration over dicts is made on keys, not values - due to the most
frequent use case. FWIW, this has been debated quite a few times here.

> x in aset # is element x in set?

> and an early implementation of Python sets used dictionaries,

And this is only an implementation detail.

> where the
> elements where stored as keys, not values. It makes no sense to treat set
> elements as if they were analogous to dict values.

Would it make sense to treat them as if they where list values ?-)

>
>> Sets have no keys, only values. One might suggest assignment of keys, à
>> la array indexes, but that means assigning an ordering to the values,
>> whereas sets are explicitly unordered.
>
> Why on earth should "del aset[x]" imply that sets are ordered? Dicts
> aren't ordered. You don't find people going "wibble wibble wibble, I
> don't understand del adict[x] because dicts aren't ordered, what could it
> mean???"

s/ordered/indexed/, and it makes perfect sense. Dicts and lists are
indexed, sets are not.


Aaron "Castironpi" Brady

unread,
Oct 5, 2008, 3:28:53 PM10/5/08
to pytho...@python.org
> --
> http://mail.python.org/mailman/listinfo/python-list

Which one has seniority? It's somewhat arbitrary which of 'pop' and
'remove' have which meanings in lists. You can 'remove' on index or
value in lists, key or value in dicts, and only value in sets.

I agree that you don't pass an 'index' to 'del' in dicts, you pass a
key. Does the OP also hold that dicts should grow a 'remove' method to
remove a value?

Lawrence D'Oliveiro

unread,
Oct 5, 2008, 6:52:14 PM10/5/08
to
In message <00f88c9e$0$20633$c3e...@news.astraweb.com>, Steven D'Aprano
wrote:

> On Sun, 05 Oct 2008 22:11:38 +1300, Lawrence D'Oliveiro wrote:
>
>> In message <00f80c6a$0$20633$c3e...@news.astraweb.com>, Steven D'Aprano
>> wrote:
>>
>>> Would it really be "confusing" if sets used the same interface as dicts
>>> use? I don't think so. What else could "del aset[x]" mean other than
>>> "delete element x"?
>>
>> Yes, but "x" in what sense?
>
> The only sense possible.

There is no precedent for using a set element as a subscript to the set.

Henk.va...@gmail.com

unread,
Oct 16, 2008, 4:29:44 PM10/16/08
to
"Life was like a box of chocolates. You never know what you're gonna
get."

Regardless of how it is implemented, mathematically a set is a
collection of items.
The order does not matter, an item is part of a set, or is not part of
a set. Period.

Henk

0 new messages