Drowning in a teacup?

Fillmore fillmore_remove at hotmail.com
Fri Apr 1 16:27:13 EDT 2016


notorious pass by reference vs pass by value biting me in the backside 
here. Proceeding in order.

I need to scan a list of strings. If one of the elements matches the 
beginning of a search keyword, that element needs to snap to the front 
of the list.
I achieved that this way:


    for i in range(len(mylist)):
         if(mylist[i].startswith(key)):
             mylist = [mylist[i]] + mylist[:i] + mylist[i+1:]

Since I need this code in multiple places, I placed it inside a function

def bringOrderStringToFront(mylist, key):

     for i in range(len(mylist)):
         if(mylist[i].startswith(key)):
             mylist = [mylist[i]] + mylist[:i] + mylist[i+1:]

and called it this way:

  if orderstring:
      bringOrderStringToFront(Tokens, orderstring)

right?
Nope, wrong! contrary to what I thought I had understood about how 
parameters are passed in Python, the function is acting on a copy(!) and 
my original list is unchanged.

I fixed it this way:

def bringOrderStringToFront(mylist, key):

     for i in range(len(mylist)):
         if(mylist[i].startswith(key)):
             mylist = [mylist[i]] + mylist[:i] + mylist[i+1:]
     return(mylist)

and:

if orderstring:
    Tokens = bringOrderStringToFront(Tokens, orderstring)

but I'm left with a sour taste of not understanding what I was doing 
wrong. Can anyone elaborate? what's the pythonista way to do it right?

Thanks




More information about the Python-list mailing list