简体   繁体   中英

Recursion results in nested lists

Running my function frisbeeSort() always results in the list being sorted but with each item being in a nested list. I would like to recursively alter the original list instead of using a temp list.

def frisbeeSort(n):
    index = n.index(min(n))
    if len(n) == 1:
        return n[0]
    else:
        n[0:index + 1] = n[index::-1]
        n = [n[0], frisbeeSort(n[1:])]
    return n

list1 = [12, 42, 34, 12, 76, 45, 13, 98, 234, 1]

I expect

[1, 12, 12, 13, 34, 42, 45, 76, 98, 234]

but I keep getting

[1, [12, [12, [13, [34, [42, [45, [76, [98, 234]]]]]]]]]

You return an item, not a list when len(n) == 1 . You are also concatenating the two lists incorrectly. Try this:

def frisbeeSort(n):
    index = n.index(min(n))
    if len(n) == 1:
        return [n[0]]
    else:
        n[0:index + 1] = n[index::-1]
        n = [n[0]] + frisbeeSort(n[1:])
    return n

list1 = [12, 42, 34, 12, 76, 45, 13, 98, 234, 1]
print(frisbeeSort(list1))

output:

[1, 12, 12, 13, 34, 42, 45, 76, 98, 234]

I would like to recursively alter the original list instead of using a temp list

Although the accepted answer addresses the "nested list" issue, I don't believe it addresses the above expectation. That is, if you do:

list1 = [12, 42, 34, 12, 76, 45, 13, 98, 234, 1]
print(frisbeeSort(list1))
print(list1)

You get:

> python3 test.py
[1, 12, 12, 13, 34, 42, 45, 76, 98, 234]
[1, 234, 98, 13, 45, 76, 12, 34, 42, 12]
>

Where list1 is altered but remains unsorted. Here's one way to go about the problem of sorting the list in-place using the OP's algorithm:

def frisbeeSort(n, start=0):
    if start < len(n):
        index = n.index(min(n[start:]), start)
        n[start:index + 1] = n[start:index + 1][::-1]
        frisbeeSort(n, start + 1)

list1 = [12, 42, 34, 12, 76, 45, 13, 98, 234, 1]
frisbeeSort(list1)
print(list1)

OUTPUT

> python3 test.py
[1, 12, 12, 13, 34, 42, 45, 76, 98, 234]
>

could you please explain what exactly changes the original list instead of returning a sorted list?

There are two things that allow this to happen. First, the (defaulted) second start argument:

def frisbeeSort(n, start=0):

which allows us to preserve the initial elements that are sorted on the recursive call:

 frisbeeSort(n, start + 1)

and tells us where to begin our new minimum search:

 index = n.index(min(n[start:]), start)

etc. Second, the assignment back into the array itself:

n[start:index + 1] = n[start:index + 1][::-1]

We're replacing the remaining unsorted elements with the same values reversed. The temporary array on right gets tossed and the original gets updated.

When you write [n[0], frisbeeSort(n[1:])] , it creates a two-element list in which the first element is n[0] and the second one is the value returned from frisbeeSort(n[1:]) (which is a list). If you want to join them into a flat list, you can write [n[0]] + frisbeeSort(n[1:]) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM