Python: add a value to the end of the most nested list on the right

What I'm trying to do is a list with an arbitrary number of other nested lists, recursively descending through the last value in the nested lists, until I reach the maximum depth, and then add the value to this list. An example might make this clearer:

>>> nested_list1 = [1, 2, 3, [4, 5, 6]] >>> last_inner_append(nested_list1, 7) [1, 2, 3, [4, 5, 6, 7]] >>> nested_list2 = [1, 2, [3, 4], 5, 6] >>> last_inner_append(nested_list2, 7) [1, 2, [3, 4], 5, 6, 7] 

The following code works, but it seems too complicated to me:

 def add_to_inner_last(nested, item): nest_levels = [nested] try: nest_levels.append(nested[-1]) except IndexError: # The empty list case nested.append(item) return while type(nest_levels[-1]) == list: try: nest_levels.append(nest_levels[-1][-1]) except IndexError: # The empty inner list case nest_levels[-1].append(item) return nest_levels[-2].append(item) return 

Some things I like:

  • Works
  • It handles row cases at the end of lists and cases of empty lists.

Some things I don't like:

  • I need to check the type of objects because rows are also indexed
  • The indexing system seems too magical - I won’t be able to figure it out tomorrow.
  • It feels too smart to use the fact that adding to a link list affects all links

Some common questions that I have:

  • At first I was worried that adding to nest_levels was ineffective, but then I realized that this was probably just a link, and a new object was not created, right?
  • This code is a purely side effect (it always returns None ). Should I be bothered by this?

Basically, although this code works (I think ...), I wonder if there is a better way to do this. For the better, I mean clearer or more pythonic. Potentially something with more explicit recursion? I was not able to determine a breakpoint or a way to do this without side effects.

Edit:

To be clear, this method should also handle:

 >>> last_inner_append([1,[2,[3,[4]]]], 5) [1,[2,[3,[4,5]]]] 

and

 >>> last_inner_append([1,[2,[3,[4,[]]]]], 5) [1,[2,[3,[4,[5]]]]] 
+4
source share
5 answers

How about this:

 def last_inner_append(x, y): try: if isinstance(x[-1], list): last_inner_append(x[-1], y) return x except IndexError: pass x.append(y) return x 
+4
source

This function returns the deepest internal list:

 def get_deepest_list(lst, depth = 0): deepest_list = lst max_depth = depth for li in lst: if type(li) == list: tmp_deepest_list, tmp_max_depth = get_deepest_list(li, depth + 1) if max_depth < tmp_max_depth: # change to <= to get the rightmost inner list max_depth = tmp_max_depth deepest_list = tmp_deepest_list return deepest_list, max_depth 

And then use it like:

 def add_to_deepest_inner(lst, item): inner_lst, depth = get_deepest_list(lst) inner_lst.append(item) 
+2
source

Here is my trick:

 def last_inner_append(cont, el): if type(cont) == list: if not len(cont) or type(cont[-1]) != list: cont.append(el) else: last_inner_append(cont[-1], el) 
  • I think it’s good and clear, and passes all your tests.
  • It is also a pure side effect; if you want to change this, I suggest you go to the BasicWolf approach and create a “selector” and “update” function in which the latter uses the former.
  • This is the same recursion scheme as Phil H, but it processes empty lists.
  • I don’t think that there is a good way to get around the two types of tests, however you are suitable for them (for example, with a “type” or “adding” ...).
+1
source

You can check if append callable and not use try / catch and recursively:

 def add_to_inner_last(nested, item): if callable(nested,append): if callable(nested[-1],append): return add_to_inner_last(nested[-1],item) else: nested.append(item) return true else: return false 

A little annoying is the need to have two callable , but the alternative is to pass the reference to the parent as well as to the child.

0
source
 def last_inner_append(sequence, element): def helper(tmp, seq, elem=element): if type(seq) != list: tmp.append(elem) elif len(seq): helper(seq, seq[-1]) else: seq.append(elem) helper(sequence, sequence) 
0
source

All Articles