Posts: 3
Threads: 2
Joined: Jan 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 ?
Posts: 3,458
Threads: 101
Joined: Sep 2016
Posts: 2,342
Threads: 62
Joined: Sep 2016
+1 to nilamo requesting the whole error, but I felt generous and ran the code:
Error: Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in deepconcat
File "<stdin>", line 11, in deepconcat
File "<stdin>", line 9, in deepconcat
File "<stdin>", line 9, in deepconcat
File "<stdin>", line 9, in deepconcat
File "<stdin>", line 11, in deepconcat
File "<stdin>", line 9, in deepconcat
File "<stdin>", line 11, in deepconcat
File "<stdin>", line 9, in deepconcat
File "<stdin>", line 9, in deepconcat
File "<stdin>", line 9, in deepconcat
TypeError: can only concatenate str (not "list") to str
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.
Posts: 817
Threads: 1
Joined: Mar 2018
x = ["a",["b","6"],"e",["5",["g","h"]],"i"]
x.__repr__().replace("[",'').replace("]". '').replace("'",'').replace(" ",'')
Posts: 2,342
Threads: 62
Joined: Sep 2016
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"]]
Posts: 817
Threads: 1
Joined: Mar 2018
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.
Posts: 1,950
Threads: 8
Joined: Jun 2018
Jan-15-2019, 09:49 AM
(This post was last modified: Jan-15-2019, 09:49 AM by perfringo.)
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]
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
|