-2

I'm learning python lists and recursive coding . I'm trying to flatten a list by altering the original, instead of returning a new list. Here is the output I get so far

     >>> list1 = [3,4,[[5]]]
     >>> list2 = [[[1, 2, list1], (6, [7]), 8], 9, False]
     >>> flatten_in_place(list2)
     >>> list2
     [1, 2, 3, 4, 5, (6, [7]), 8, 9, False]
     >>> list1
     [3, 4, [[5]]]

As you can see I successfully flatten some of list2 properly, but [3,4,[[5]]] remains unflattened. I want it to become [3, 4, 5].

My Code :

 def flatten(lst):

   if lst == []:
       return lst
   if type(lst[0]) ==  type(lst):
       return flatten(lst[0]) + flatten(lst[1:])
   return lst[:1] + flatten(lst[1:])

 def flatten_in_place(lst):


    if lst == []:
      lst
    if type(lst[0]) ==  type(lst):
      lst[:]  = flatten(lst[0]) + flatten(lst[1:])

    lst[:] = lst[:1] + flatten(lst[1:])

Now I think I should add another recursion for the inner lists , but I don't have any idea how to do it.

Prune
  • 76,765
  • 14
  • 60
  • 81
Batata
  • 21
  • 1
  • 6
  • The code you've posted is not syntactically valid. Can you clean it up so that we can tell what it's doing? Also, try to follow SO guidelines and make it as minimal as possible. If the code in the triple quotes isn't being used, then don't include it. – user3030010 Nov 23 '16 at 18:09
  • Your test for recursion relies on it being a `list` - `(6, [7])` is a `tuple`. You need to expand your test to include other collection types. – AChampion Nov 23 '16 at 18:10
  • 1
    Possible duplicate of [Flatten (an irregular) list of lists in Python](http://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists-in-python) – AChampion Nov 23 '16 at 18:12
  • @AChampion It's not , now i updated the code see what i want to change . [3,4,[[5]]] to [3, 4, 5] – Batata Nov 23 '16 at 18:13
  • This code still doesn't run. **flatten** is not defined. When I change all calls to just "flatten", I get a run-time error when **lst** is empty. In short, your posted code does not reproduce the problem. – Prune Nov 23 '16 at 18:30
  • @Prune sorry i forget to post the other part – Batata Nov 23 '16 at 18:32
  • Also, you haven't explained how your question is different from the cited duplicate. – Prune Nov 23 '16 at 18:35
  • @Prune look at list2 before and after in the example – Batata Nov 23 '16 at 18:38
  • Right; you didn't finish flattening (6, [7]) because it's a tuple, and your code handles only sub-elements with the same type as the parent. The cited duplicate does the full flattening. I assume that you meant (6, [7]) in your comment, rather than [3, 4, [[5]]], since you *did* successfully flatten the latter. – Prune Nov 23 '16 at 18:43
  • @Prune no i meant list2 l, Tuple cant be editted as i know i want to change the list that is in the list as show in the example – Batata Nov 23 '16 at 18:45
  • Got it. The confusing part was "As you can see", which implies that I'm looking at your *actual* output. You're supposed to supply both -- it's stated in the introductory tour you're supposed to finish before posting. – Prune Nov 23 '16 at 18:48
  • @Prune im so sorry , i would do better in the next questions :) – Batata Nov 23 '16 at 18:51
  • That's why the rest of us are here: to help you become a better programmer, and to guide you in describing problems. English is not the easiest language. – Prune Nov 23 '16 at 18:59

1 Answers1

0

< Original code removed>

EDIT in response to comment.

This is going to be tricky, then. Note that, when you flatten list2, the final result no longer includes list1: we now have three new elements -- 3, 4, 5 -- in place of list1.

The trick, then, is to consider each element of the list in turn, recurring on that element first, replacing any list elements, and then returning to the caller.

So here is a solution that works. At each call, it iterates through the list, building a result list. Any list-type element of the input list gets fed to a recursive call.

The painful part of this is the case in which the list length alters, such as turning the 2-element list [1, [2, 3]] into the 3-element list [1, 2, 3]. To effect this change without changing the base object pointer, I work in three steps:

  1. Build a new list, the flattened version of the input list.
  2. Pop all of the elements out of the original list; this leaves an empty list, but under the original object handle.
  3. Append each element of the result list to the original list.

This preserves side effects to sub-elements of the original list. However, note that there is still no way to keep that relationship in place after the flattening: the original list no longer contains the sub-list; rather, it contains new references to the sub-list's elements, in order.

def flatten_in_place(lst): 

    # print "ENTER in_place", lst
    result = []
    for i in range(len(lst)):
        if type(lst[i]) == type([]):
            result.extend(flatten_in_place(lst[i]))
        else: 
            result.append(lst[i])
        # print "Loop", i, "result =", result

    # print "After loop, lst =", lst
    for _ in range(len(lst)):
        lst.pop()
    for _ in range(len(result)):
        lst.append(result[_])
    # print "LEAVE in_place", lst
    return result


list1 = [3, 4, [[5]]]
list2 = [[[1, 2, list1], (6, [7]), 8], 9, False]
flatten_in_place(list2)
print ("list2 flattened", list2)
# [1, 2, 3, 4, 5, (6, [7]), 8, 9, False]
print ("list1 affected", list1)
# [3, 4, 5]

I'll leave any improvements as an exercise for the student -- or other SO denizens.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • :/ if that was the problem , it would be too easy to make , and i wont ask this question ! i want the inner list to change just by calling the first one – Batata Nov 23 '16 at 19:54
  • Ah, ha! Okay. In that case, the problem is that **flatten** doesn't alter anything; rather, it *returns* the flattened list without changing the original. – Prune Nov 23 '16 at 21:28
  • Thanks sir !! i have one more question is it possible to implement the same function without return ?! – Batata Nov 24 '16 at 12:50
  • Of course -- provided that you don't depend on that value. If you'll notice, I did not actually use it in my solution. – Prune Nov 28 '16 at 18:04