[Python-ideas] str.rreplace
Steven D'Aprano
steve at pearwood.info
Tue Jan 28 13:33:50 CET 2014
On Mon, Jan 27, 2014 at 08:03:54PM -0800, Andrew Barnert wrote:
> From: Ron Adam <ron3200 at gmail.com>
> > How about a keyword to specify which end to index from?
-1
As a general rule, when you have a function that takes a parameter which
selects between two different sets of behaviour, and you normally
specify that parameter as a literal or constant known at edit time, then
the function should be split into two.
E.g.:
# Good API
string.upper(), string.lower()
# Bad API
string.convert_case(to_upper=True|False)
sorted() and list.sort() (for example) are a counter-example. Sometimes
you know which direction you want at edit-time, but there are many
use-cases for leaving the decision to run-time. Nearly every application
that sorts data lets the user decide which direction to sort.
In the case of replace/rreplace, it is more like the upper vs. lower
situation than the sorted situation. For almost any reasonable use-case,
you will know at edit-time whether you want to go from the left or from
the right, so you'll specify the "direction" parameter as a edit-time
literal or constant. The same applies to find/rfind.
> > When used, it would
> > disable negative indexing as well.
-1
Negative indexing is a standard Python feature. There is nothing wrong
with negative indexing, no more than there is something wrong with
zero-based positive indexing.
It's also irrelevant to the replace/rreplace example, since replace
doesn't take start/end indexes, and presumably rreplace wouldn't either.
> > When not used the current behaviour with
> > negative indexing would be the default.
> >
>
> > direction=0 # The default with the current
> > (or not specified) # negative indexing allowed.
> >
> > direction=1 # From first. Negative indexing disallowed.
> > direction=-1 # From last. Negative indexing disallowed.
And if you want to operate from the right, with negative indexing
allowed? But really, having a flag to decide whether to allow negative
indexing is silly. If you don't want negative indexes, just don't use
them.
> > (A shorter key word would be nice, but I can't think of any that is as
> > clear.)
>
> Why does it have to be -1/0/1 instead of just True/False?
>
> In which case we could use "reverse", the same name that's already
> used for similar things in other methods like list.sort (and that's
> implied in the current names "rfind", etc.).
sorted(alist, reverse=True) gives the same result as sorted(alist,
reverse=False) only reversed. That is not the case here:
"Hello world".replace("o", "u", 1, reverse=True) # rreplace
ought to return "Hello wurld", not "dlrow ulleH".
> > The reason for turning off the negative indexing is it would also offer a way to
>
> > avoid some indexing bugs as well. (Using negative indexing with a reversed
> > index is just asking for trouble I think.)
>
> But str.rfind takes negative indices today:
>
> >>> 'abccba'.rfind('b', -5, -3)
> 1
>
> Why take away functionality that already works?
Exactly. Here, I agree strongly with Andrew. Negative indexing works
perfectly well with find/rfind. Slices with negative strides are weird,
but negative indexes are well-defined and easy to understand.
> And of course str.find takes negative indices and that's actually used
> in some quick&dirty scripts:
>
> >>> has_ext = path.find('.', -4)
>
> Of course you could make an argument that any such scripts deserve to
> be broken…
It would be an awfully bogus argument. Negative indexes are a
well-defined part of Python indexing semantics. One might as well argue
that any scripts that rely on list slicing making a copy "deserve to be
broken".
--
Steven
More information about the Python-ideas
mailing list