On Sun, Dec 30, 2012 at 5:03 AM, MRAB <python@mrabarnett.plus.com> wrote:
On 2012-12-30 03:25, David Kreuter wrote:
Hi python-ideas.

I think it would be nice to have a method in 'list' to replace certain
elements by others in-place. Like this:

     l = [x, a, y, a]
     l.replace(a, b)
     assert l == [x, b, y, b]

The alternatives are longer than they should be, imo. For example:

     for i, n in enumerate(l):
         if n == a:
             l[i] = b

Or:

     l = [b if n==a else n for n in l]

And this is what happens when someone tries to "optimize" this process.
It totally obscures the intention:

     try:
         i = 0
         while i < len(l):
             i = l.index(a, i)
             l[i] = b
             i += 1
     except ValueError:
         pass

If there is a reason not to add '.replace' as built-in method, it could
be implemented in pure python efficiently if python provided a version
of '.index' that returns the index of more than just the first
occurrence of a given item. Like this:

     l = [x, a, b, a]
     for i in l.indices(a):
         l[i] = b

So adding .replace and/or .indices… Good idea? Bad idea?

What's your use-case?

I personally can't remember ever needing to do this (or, if I have, it
was so long ago that I can't remember it!).

Features get added to Python only when someone can show a compelling
reason for it and sufficient other people agree.
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
http://mail.python.org/mailman/listinfo/python-ideas

When I write code for processing graphs it becomes very useful. For example:

    def collapse_edge_undirected_graph(a, b):
        n = Node()
        n.connected = a.connected + b.connected
        for x in a.connected:
            x.connected.replace(a, n)
        for x in b.connected:
            x.connected.replace(b, n)

In other cases one would probably just add another layer of indirection.

    x = Wrapper("a")
    y = Wrapper("y")
    a = Wrapper("a")

    l = [x, a, y, a]
    a.contents = "b" # instead of l.replace(a, b)

But having to add .contents everywhere makes it messy. Graph code is complicated enough as it is.

And '.index' is a basically a resumable search. But instead of using a iterator-interface it requires the user to call it repeatedly.
A method '.indices' returning a generator seems more like the python way to approaching this.