Reputation: 167
See the function below. What I want this to do is take any string I send it, search for the '[' and ']' characters. If they exist, this portion of text is split out, the brackets are removed and it's turned into a dict. I then try to match any of the values from the dict to the attrs list. If there is a match, this value is then inserted back into the original string, and we call the function again with the new string. The conditional then checks if there are more brackets, and if not, the new string is returned.
But when I run the code, the value I get back for text1 is None. I put the print statement in the else clause to see what's coming through there, and the new string is printed as I would expect, but this string isn't getting passed back in the return statement.
When I call the function with text2, which is an identical string to the one I'm expecting text1 to hold, the value is indeed the original string assigned to string2.
import ast
string1 = "Lorem ipsum dolor sit amet, consectetur adipisicing elit [{'do':'said', 'eiusmod':'tempor', 'incididun':'ut'}]"
string2 = "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
def formatter(content):
if content.find('[') >= 0:
attrs = ['do', 'fum']
ind, indend = content.find('['), content.find(']')
choice = ast.literal_eval(content[ind+1:indend])
for attr in attrs:
for key, value in choice.iteritems():
if attr == key:
new_choice = choice[key]
new_string = content[:ind] + new_choice + content[indend+1:]
formatter(new_string)
else:
return content
text1 = formatter(string1)
text2 = formatter(string2)
print text1
print text2
Upvotes: 0
Views: 60
Reputation: 8181
I've tweaked your code a little bit to make it clearer what's happening:
import ast
string1 = "Lorem ipsum dolor sit amet, consectetur adipisicing elit [{'do':'said', 'eiusmod':'tempor', 'incididun':'ut'}]"
string2 = "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
def formatter(content):
print "content: %s" % content
if content.find('[') >= 0:
print "running if"
attrs = ['do', 'fum']
ind, indend = content.find('['), content.find(']')
choice = ast.literal_eval(content[ind+1:indend])
for attr in attrs:
for key, value in choice.iteritems():
if attr == key:
new_choice = choice[key]
new_string = content[:ind] + new_choice + content[indend+1:]
print "calling formatter with: %s" % new_string
formatter(new_string)
print "back from recursion"
else:
print "running else"
print content
return content
print "string1"
print formatter(string1)
print "string2"
print formatter(string2)
If you look at the output you'll see that on the first pass a [
is found, so we descend into the if
clause. attr == key
is found to be true in one case, so we descend into the inner if clause, and then trigger the recursive call to formatter(new_string)
On that call, there's no [
so content
gets returned back up to the original run of formatter... where it's discarded as the output from the recursive call to formatter()
is not assigned to anything.
The loop eventually ends and execution ends, with nothing being returned from the function.
If you want to bubble content
back up the call stack, you'll have to catch the return from the recursive call and do something with it. You'll need to return it eventually, but if you want to catch all matches you'll want to do something like build up a list of return values as you iterate over attrs
and then return the whole list at the end.
Upvotes: 1