invert or reverse a string... warning this is a rant

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sat Oct 21 09:07:37 CEST 2006


On Fri, 20 Oct 2006 16:17:09 +0200, Fredrik Lundh wrote:

> Tim N. van der Leeuw wrote:
> 
>> In practice, the short-term fix would be to add a __str__ method to the
>> 'reversed' object
> 
> so what should
> 
>     str(reversed(range(10)))
> 
> do ?

The same as str(range(9, -1, -1)) perhaps?

I notice that reversed() already special-cases lists:

>>> reversed(tuple(range(5)))
<reversed object at 0xb7c91d0c>
>>> reversed("01234")
<reversed object at 0xb7c91b8c>

but:

>>> reversed(range(5))
<listreverseiterator object at 0xb7c91b8c>


I'm not sure why it would do such a thing -- something to do with mutable
versus immutable arguments perhaps? It is surprising that x and
reversed(x) aren't the same type. This is even more surprising:

>>> list(reversed(range(5)))
[4, 3, 2, 1, 0]
>>> tuple(reversed(tuple(range(5))))
(4, 3, 2, 1, 0)

but 

>>> str(reversed("01234"))
'<reversed object at 0xb7c91b8c>'

It could be argued that people shouldn't be reversing strings with
reversed(), they should use slicing. But I'll argue that "shouldn't" is
too strong a prohibition. Python, in general, prefers named methods and
functions for magic syntax, for many good reasons. (e.g. a str.reverse()
method could have a doc string; str[::-1] can't.) reversed() is designed
to work with sequences, and strings are sequences; it is a recent addition
to the language, not a hold-over from Ancient Days; and since nobody seems
to be arguing that reversed shouldn't be used for other sequence types,
why prohibit strings?

This is not an argument *against* slicing -- obviously slicing is too
fundamental a part of Python to be abandoned. But since reversed() exists,
it should do the right thing. Currently it does the right thing on lists
and tuples, but not on strings.

Perhaps the solution is to special case strings, just like lists are
special cased. Ordinary reversed objects needn't change, but reversed(str)
returns a strreverseiterator that has a __str__ method that does the right
thing. That's just a suggestion, I daresay if it is an awful suggestion
people will tell me soon enough.


-- 
Steven.




More information about the Python-list mailing list