0

Some days ago I ask for some function that retrieve the repetitive motif from some string (Here the link to the ask). The user @Kasramvd posted a nice function based on regex:

import re
def finder(st,past_ind=0,l=[]):
    m=re.search(r'(.+)\1+',st)
    if m:
        i,j=m.span()
        sub=st[i:j]
        ind = (sub+sub).find(sub, 1)
        sub=sub[:ind]
        if len(sub)>1:
            l.append([sub,(i+past_ind+1,j+past_ind+1)])
        past_ind+=j
        return finder(st[j:],past_ind)
    else:
        return l

This function, in fact, catch the repetitive motifs and also show the from/until where it take place:

>>> finder('123.123.123.')
[['123.', (1, 13)]] #the 123. motif take place from position 1 to position 13

However, looks like this function has memory. When I used it again with other string, it show also the previous result:

>>> finder('abc.abc.abc.')
[['123.', (1, 13)], ['abc.', (1, 13)]]

So, someone know how to avoid this? How to reset the function?

Thanks in advance guys. =)

Community
  • 1
  • 1
Ivan Castro
  • 581
  • 2
  • 10
  • 22

1 Answers1

1

Don't use mutable types for function defaults.

When you declare def finder(st,past_ind=0,l=[]), the default value is a single list which is shared between all invocations of the function that don't override the default (and returned to the caller to boot), so any mutations made to the list within the function or by the caller will change the default for future calls. Changing to:

def finder(st,past_ind=0,l=None):
    if l is None:
        l = []
    ... rest of function ...

avoids this problem; the assignment to l within the function body creates a new list each time.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • This is more of a comment than an answer. – Leb Sep 25 '15 at 00:57
  • You rock, dude! But also it is important to say that the line `return finder(st[j:],past_ind)` must be changed to `return finder(st[j:],past_ind, l=l)` – Ivan Castro Sep 25 '15 at 01:16