Recursivity - Problem - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Recursivity - Problem (/thread-15364.html) |
Recursivity - Problem - SupaFlamme - Jan-14-2019 Hi, I got a problem this code : def deepconcat(l) : if l == [] : return None elif len(l) == 1 : return l[0] else : for i in l : if type(i) == str : return l[0] + deepconcat(l[1:]) if type(i) == list : return deepconcat(i+l[1:])I have to turn ["a",["b","6"],"e",["5",["g","h"]],"i"] into "ab6e5ghi". It works. If I add a string at the end of the list, for example : ["a",["b","6"],"e",["5",["g","h"]],"i","o"], it works. But when I add a sub list, for example : ["a",["b","6"],"e",["5",["g","h"]],"i",["k"]], I have a TypeError. I don't understand why, could you please help me ? RE: Recursivity - Problem - nilamo - Jan-14-2019 What's the whole error? RE: Recursivity - Problem - micseydel - Jan-14-2019 +1 to nilamo requesting the whole error, but I felt generous and ran the code: When I started digging into your code I realized that you're returning within a loop such that the loops is misleading, you only ever look at the first element (for input composed only of strings and lists). I would suggest that you either (1) get rid of that loop or (2) make the loop not return on the first iteration. I think once you do that that your code will be more clear and easier for you and us to debug.
RE: Recursivity - Problem - scidam - Jan-15-2019 x = ["a",["b","6"],"e",["5",["g","h"]],"i"] x.__repr__().replace("[",'').replace("]". '').replace("'",'').replace(" ",'') RE: Recursivity - Problem - micseydel - Jan-15-2019 scidam that's an interesting solution but it's less generic given an input like so: ['"', "a", '"']For the original poster - a heavier hint is that you should trace your code for the following input: [["1"]] RE: Recursivity - Problem - scidam - Jan-15-2019 I just ran the code with ['"', "a", '"'] as input and it works fine for me, I got: '"a"' . It also works for deeply nested lists. In any case I am agreeing with that the recursive traversing this nested structure is more generic.
RE: Recursivity - Problem - perfringo - Jan-15-2019 Some observations: - function can return three different datatypes: None, int and str. Whatever usage follows, it must be very defensive (None if empty list, int if list with one integer, string as expected result) - for me personally it's more natural to return only one datatype. In case of empty list it should be empty string - it works only when elements are strings, otherwise TypeError will be raised It's of course upon specific needs but nevertheless I would have solved this problem differently. I would have separated flattening the list and manipulating list elements. I would have created stream of elements of flattened list: def flat_stream(lst): for item in lst: if isinstance(item, (list, tuple)): yield from flat_stream(item) else: yield item This returns generator object which is memory efficient. It preserves all elements in their original type (which is often needed). Now I can manipulate this stream whatever way I want: >>> ls = ["a",["b","6"],"e",["5",["g","h"]],"i",["k"]] >>> ''.join(el for el in flat_stream(ls)) 'ab6e5ghik' >>> list(flat_stream(ls)) ['a', 'b', '6', 'e', '5', 'g', 'h', 'i', 'k']If there are different types of elements and I want to manage them differently (data often needs verifying, cleansing etc) then I can do it: >>> ls = ["a",("b","6"),"e",[5,["g","h"]],"i",["k"]] # there is int and tuple in list >>> ''.join(str(el) for el in flat_stream(ls)) # convert all elements to str 'ab6e5ghik' >>> ''.join(el for el in flat_stream(ls) if isinstance(el, str)) # ignore int 'ab6eghik' >>> [el for el in flat_stream(ls) if not isinstance(el, str)] # ignore strings [5] |