Reputation: 55
I have made:
def collatz(b):
l=[b]
if b==1:
return 1
elif b%2==0:
l.append(collatz(b/2))
else:
l.append(collatz(b*3+1))
return l
but, the output like this:
>>>[21, [64, [32, [16, [8, [4, [2, 1]]]]]]]
how to make the output like this(with recursive function):
>>>Collatz: 21 64 32 16 8 4 2 1
Upvotes: 2
Views: 2133
Reputation: 180481
As tobias already answered, you need to extend not append to get a flat list but you can use also an if/else returning [b] + collatz...
to get a flat list of values returned:
def collatz(b):
if b == 1:
return [b]
return [b] + collatz(b / 2) if not b % 2 else [b] + collatz(b * 3 + 1)
You can format the output however you want with a print:
In [5]: from __future__ import print_function
In [6]: print("Collatz :",*collatz(20))
Collatz : 20 10 5 16 8 4 2 1
You should probably also make sure that the input is non negative or you will end up a RuntimeError.
Upvotes: 3
Reputation: 82929
Use extend
instead of append
, and make sure to always return a list, to return a "flat" list:
def collatz(b):
l=[b]
if b==1:
return [1] # wrapped in list
elif b%2==0:
l.extend(collatz(b/2)) # extend
else:
l.extend(collatz(b*3+1)) # extend
return l
Or maybe a bit more concise:
def collatz(b):
if b == 1:
return [b]
elif b%2==0:
return [b] + collatz(b/2)
else:
return [b] + collatz(b*3+1)
If you want to return that Collatz:
prefix, you have to use a wrapper function:
def collatz(x):
def collatz_inner(b):
if b == 1:
return [b]
elif b%2==0:
return [b] + collatz_inner(b/2)
else:
return [b] + collatz_inner(b*3+1)
return "Collatz: " + ' '.join(map(str, collatz_inner(x)))
Upvotes: 3