Andrew Durdin <[EMAIL PROTECTED]> wrote: > On 29 Dec 2005 09:50:57 -0800, colinwb <[EMAIL PROTECTED]> wrote: > > > > >> puts ck.first, ck[0], '*', ck.last, ck[-1] > > One of the points at issue (minimalism/monotony) relates to TOOWTDI, > which has implications for language/module design and for code > readability. Ruby supports negative indices in the same way as Python, > so why add .last as an alias for [-1]? It's just added mental baggage.
In this particular case, it can be opined that it's more readable to code goo.last than goo[-1]. For an analogy, consider, in Python, somestr.startswith('glab') as a more readable equivalent of somestr[:4]=='glab' -- the "why add?" question is easily answered, although it's of course possible to disagree with the specific decision made in each and every single case in which the same functionality is provided in two distinct ways. Python has a LOT of cases in which you can get the same functionality in distinct ways, and not all of them are judged to fall afoul of the "there should ideally be only one way" principle. Operations that have to do with slicing of sequences are a substantial class of this "added mental baggage", and not just for strings' endswith and startswith methods. Consider, for example: del somelist[start:finish] somelist[start:finish] = [] exactly identical semantics. Or: somelist.extend(another) somelist[len(somelist):] = another or (for suitable values of i, only): somelist.insert(i, blah) somelist[i-1:i] = [blah] or acopy = somelist[:] acopy = list(somelist) In each case, one could argue that the named alternative (del, extend, insert, list, ...) is more readable; but the slice-based alternative is also provided because slicing is such a powerful and general tool, and when you're computing the slice's boundaries at runtime it's precious. So, I don't think it would violate the spirit of Python to have somelist.last mean the same as somelist[-1], e.g.: class listwithlast(list): def getLast(self): return self[-1] def setLast(self, value): self[-1] = value last = property(getLast, setLast) Such tradeoffs need to be decided case by case, and, in Python, they have been -- e.g., there's no "somelist.getodd()" synonym for somelist[::2], for example;-). I think the myriad specific decisions and trade-offs may be disputed (and it's not impossible that a strong enough case can be made for one more such "synonym", so that a PEP proposing it might in theory be accepted for a future Python version), but essentially only on a case by case basis (it's good to keep in mind principles such as "all other things being equal it's better to have one way than more than one", of course, while taking such decisions). I do draw the line at foo.size being defined as identical to foo.length, which I personally classify as a design error (I don't think Python is exempt from design errors at this minute level, either -- e.g., the method name 'setdefault' is murky, though I can't propose a better one, and the existence of both pop and popitem in dictionaries appears to cause more confusion than benefit, where it might have sufficed to make pop's argument optional if one wanted popitem's functionality). > And if you think .last is significantly more readable or convenient > than [-1], why not add .secondlast ? And .first, and .second ? With > one simple, obvious, general interface, these special cases only add > unneeded complexity. first and last make sense (though it's debatable whether they should exist or not, it's not obvious that they're design errors, not at all); second, penultimate, and other variations, would be gilding the lily. Just like startswith and endswith may (debatably) make sense, but, say, hasrightinthemiddle would be surely inappropriate;-) Alex -- http://mail.python.org/mailman/listinfo/python-list