Reputation: 2992
I'm trying to implement a recursive function and have run into some difficulties, would appreciate your thoughts. As an example, let's try to create a function called sliding
that does this
sliding("python", 2)
["py", "yt", "th", "ho", "on"]
That is, for the chosen integer, we slide along the string, grabbing substrings of the appropriate length, and then return them all in a list.
Now here's how I might (foolishly) try to define this recursively:
def sliding(string,k):
return s if len(string)==k else [string[:k]].append(sliding(string[1:],k))
This will not work, mainly because list.append()
happens in place and returns a None
. So my question is - Is there a way to do this kind of recursive function even though lots of Python methods occurs in place?
Here's the best I've got so far,
def sliding(s,k):
if len(s)==k:
return s
else:
temp = [s[:k]]
temp.append(sliding(s[1:],k) )
return temp
This results in
sliding("python",k=2)
['py', ['yt', ['th', ['ho', 'on']]]]
which is obviously not quite the desired output, but is in the right direction. What other ways might there be to do this? Thanks for your thoughts.
Upvotes: 3
Views: 499
Reputation: 2140
Here are both iterative and recursive versions:
def sliding(s, window=2):
for ind in range(len(s) - (window - 1)):
yield s[ind:ind+window]
def sliding_recursive(s, window=2, ind=0):
if ind > len(s) - window:
return []
strings = [s[ind: ind+window]] + sliding_recursive(s, window, ind+1)
return strings
>>> list(sliding('python'))
['py', 'yt', 'th', 'ho', 'on']
>>> list(sliding('python', window=3))
['pyt', 'yth', 'tho', 'hon']
>>> sliding_recursive('python')
['py', 'yt', 'th', 'ho', 'on']
>>> sliding_recursive('python', window=3)
['pyt', 'yth', 'tho', 'hon']
Upvotes: 1
Reputation: 41186
I'd suggest:
temp.extend(sliding(s[1:],k) )
instead of append since you'll be getting lots of imbricated objects.
Upvotes: 0
Reputation: 23261
Solution without recursion, just small play on slice syntax.
def sliding(s, i):
return [s[n:n+i] for n in xrange(len(s)-i+1)]
assert sliding("python", 2) == ["py", "yt", "th", "ho", "on"]
assert sliding("python", 3) == ["pyt", "yth", "tho", "hon"]
Upvotes: 3
Reputation: 13158
How about this?
def sliding(string, k):
return [string[i:i+k] for i in range(len(string)-k+1)]
Upvotes: 1
Reputation: 18552
Use the +
operator to get a new concatenated list:
def sliding(s, k):
if len(s) < k: return []
else: return [s[:k]] + sliding(s[1:], k)
Upvotes: 5