Search code examples
pythonselection-sort

Selection Sorter, but i want the output to merge


So I want to make a sorter, but I want it the output to merge. In my code, I separated the two different type variables from the list, the integer and int.

List:

nlist = [19, 5, 'cat', 'rabbit', 2, 32, 'mice', 'dog', 7]

Code:

def bubble(collection):
    dlist = [e for e in collection if isinstance(e, int)]
    clist = [e for e in collection if not isinstance(e, int)]
    for endnum in range(len(dlist)-1, 0, -1): 
        print(dlist)
        for i in range(endnum):
            if dlist[i] > dlist[i+1]:
                dlist[i], dlist[i+1] = dlist[i+1], dlist[i]
    for endnumm in range(len(clist)-1, 0, -1): 
        print(clist)
        for j in range(endnumm):
            if clist[j] > clist[j+1]:
                clist[j], clist[j+1] = clist[j+1], clist[j]
    answer = dlist + clist
    print(answer)

Output:

[19, 5, 2, 32, 7]
[5, 2, 19, 7, 32]
[2, 5, 7, 19, 32]
[2, 5, 7, 19, 32]
['cat', 'rabbit', 'mice', 'dog']
['cat', 'mice', 'dog', 'rabbit']
['cat', 'dog', 'mice', 'rabbit']
[2, 5, 7, 19, 32, 'cat', 'dog', 'mice', 'rabbit']

Required Output:

[19, 5, 'cat', 2, 'rabbit', 32, 'mice', 'dog', 7]
[19, 5, 'cat', 2, 32, 'rabbit', 'mice', 'dog', 7]
[19, 5, 'cat', 2, 32, 'rabbit', 'mice', 7, 'dog']
[19, 5, 2, 'cat', 32, 'rabbit', 'mice', 7, 'dog']
[19, 5, 2, 32, 'cat', 'rabbit', 'mice', 7, 'dog']
[19, 5, 2, 32, 'cat', 'rabbit', 7, 'mice', 'dog']
[19, 5, 2, 32, 'cat', 7, 'rabbit', 'mice', 'dog']
[19, 5, 2, 32, 7, 'cat', 'rabbit', 'mice', 'dog']
[5, 19, 2, 32, 7, 'cat', 'rabbit', 'mice', 'dog']
[5, 2, 19, 32, 7, 'cat', 'rabbit', 'mice', 'dog']
[5, 2, 19, 7, 32, 'cat', 'rabbit', 'mice', 'dog']
[5, 2, 19, 7, 32, 'cat', 'rabbit', 'mice', 'dog']
[2, 5, 19, 7, 32, 'cat', 'rabbit', 'mice', 'dog']
[2, 5, 7, 19, 32, 'cat', 'rabbit', 'mice', 'dog']
[2, 5, 7, 19, 32, 'cat', 'mice', 'rabbit', 'dog']
[2, 5, 7, 19, 32, 'cat', 'mice', 'dog', 'rabbit']
[2, 5, 7, 19, 32, 'cat', 'dog', 'mice', 'rabbit']

Is there any way that I can make the output to the required output?

Same dude earlier just fixed some problems and the question.


Solution

  • The general approach

    You can approach this problem by considering that your "greater than" relation is a little more complex than just Python's >:

    • for two numbers, > applies,
    • for two strings, > applies,
    • between any number and any string, the string is "greater than" the number.

    Now, implement a function that does that, and use it instead of > in your algorithm.

    Implementing that approach

    Let's write that logic into function my_greater_than:

    def my_greater_than(a, b):
        """greater than where an int is "smaller" than other things"""
        if isinstance(a, int):
            if isinstance(b, int):
                return a > b
            else:
                return False
        else:
            if isinstance(b, int):
                return True
            else:
                return a > b
    

    You'll notice here I took a shortcut: I don't check for str, I just check for int and assume str in the else clauses.

    That's quite verbose, for clarity, but we can write the same logic more concisely, like this:

    def my_greater_than(a, b):
        """greater than where an int is "smaller" than other things"""
        if isinstance(a, int):
            return isinstance(b, int) and a > b
        else:
            return isinstance(b, int) or a > b
    

    Now, let's use this in place of > in your bubble sort code. I'm keeping exactly your bubble sort algorithm, but calling it just once with our greater than function used on the whole list.

    def bubble(collection):
        my_list = list(collection)
        for endnum in range(len(my_list)-1, 0, -1): 
            print(my_list)
            for i in range(endnum):
                if my_greater_than(my_list[i], my_list[i+1]):
                    my_list[i], my_list[i+1] = my_list[i+1], my_list[i]
        print(my_list)
    

    And now we can call it on your list to get the output you want:

    nlist = [19, 5, 'cat', 'rabbit', 2, 32, 'mice', 'dog', 7]
    bubble(nlist)
    

    prints

    [19, 5, 'cat', 'rabbit', 2, 32, 'mice', 'dog', 7]
    [5, 19, 'cat', 2, 32, 'mice', 'dog', 7, 'rabbit']
    [5, 19, 2, 32, 'cat', 'dog', 7, 'mice', 'rabbit']
    [5, 2, 19, 32, 'cat', 7, 'dog', 'mice', 'rabbit']
    [2, 5, 19, 32, 7, 'cat', 'dog', 'mice', 'rabbit']
    [2, 5, 19, 7, 32, 'cat', 'dog', 'mice', 'rabbit']
    [2, 5, 7, 19, 32, 'cat', 'dog', 'mice', 'rabbit']
    [2, 5, 7, 19, 32, 'cat', 'dog', 'mice', 'rabbit']
    [2, 5, 7, 19, 32, 'cat', 'dog', 'mice', 'rabbit']
    

    Additional notes

    • You might notice I took a copy of collection into my_list on the first line of bubble(). That's because I don't want to modify the input list I was provided. If we worked directly on collection, we would find nlist also sorted after calling bubble().
    • The other reason to copy the collection with a call to list() is that it lets us accept anything iterable. Collections could be a set, a list, a tuple, a dictionary or any other iterable in Python, and our sort function would work on it anyway.
    • I print the output because that's what you did, but I would normally have had a return statement in there: replace print(my_list) on the last line of bubble() by return my_list.