Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add append update and extend in python

Is there an article or forum discussion or something somewhere that explains why lists use append/extend but sets and dicts use add/update.

I frequently find myself converting lists into sets and this difference makes that quite tedious so for my personal sanity I'd like to know what the rationalization is.

The need to convert between these occurs regularly as we iterate on development. Over time as the structure of the program morphs various structures gain and lose requirements like ordering and duplicates.

For example something that starts out as an unordered bunch of stuff in a list might pick up the the requirement that there be no duplicates and so need to be converted to a set.

All such changes require finding and changing all places where the relevant structure is added/appended and extended/updated.

So I'm curious to see the original discussion that led to this language choice, unfortunately I've had no luck googling for it.

like image 744
Gordon Wrigley Avatar asked Jul 05 '10 23:07

Gordon Wrigley


2 Answers

append has a popular definition of "add to the very end", and extend can be read similarly (in the nuance where it means "...beyond a certain point"); sets have no "end", nor any way to specify some "point" within them or "at their boundaries" (because there are no "boundaries"!), so it would be highly misleading to suggest that these operations could be performed.

x.append(y) always increases len(x) by exactly one (whether y was already in list x or not); no such assertion holds for s.add(z) (s's length may increase or stay the same). Moreover, in these snippets, y can have any value (i.e., the append operation never fails [except for the anomalous case in which you've run out of memory]) -- again no such assertion holds about z (which must be hashable, otherwise the add operation fails and raises an exception). Similar differences apply to extend vs update. Using the same name for operations with such drastically different semantics would be very misleading indeed.

it seems pythonic to just use a list on the first pass and deal with the performance on a later iteration

Performance is the least of it! lists support duplicate items, ordering, and any item type -- sets guarantee item uniqueness, have no concept of order, and demand item hashability. There is nothing Pythonic in using a list (plus goofy checks against duplicates, etc) to stand for a set -- performance or not, "say what you mean!" is the Pythonic Way;-). (In languages such as Fortran or C, where all you get as a built-in container type are arrays, you might have to perform such "mental mapping" if you need to avoid using add-on libraries; in Python, there is no such need).

Edit: the OP asserts in a comment that they don't know from the start (e.g.) that duplicates are disallowed in a certain algorithm (strange, but, whatever) -- they're looking for a painless way to make a list into a set once they do discover duplicates are bad there (and, I'll add: order doesn't matter, items are hashable, indexing/slicing unneeded, etc). To get exactly the same effect one would have if Python's sets had "synonyms" for the two methods in question:

class somewhatlistlikeset(set):
    def append(self, x): self.add(x)
    def extend(self, x): self.update(x)

Of course, if the only change is at the set creation (which used to be list creation), the code may be much more challenging to follow, having lost the useful clarity whereby using add vs append allows anybody reading the code to know "locally" whether the object is a set vs a list... but this, too, is part of the "exactly the same effect" above-mentioned!-)

like image 172
Alex Martelli Avatar answered Sep 19 '22 12:09

Alex Martelli


set and dict are unordered. "Append" and "extend" conceptually only apply to ordered types.

like image 37
Ignacio Vazquez-Abrams Avatar answered Sep 16 '22 12:09

Ignacio Vazquez-Abrams