Python - Cannot sort properly my list by alphabetical order

126 Views Asked by At

I had to create my own "sorted" function by alphabetical order, and then to use than function in an other. The aim is to sort a list by alphabetical number, my test list has 4 elements, but the final aim is to apply this function to a huge list, this is why i'm trying it on a few elements first, because it's easier to analyse the results.

here is the function that sort by alphabetical order :

def alphaOrder(word1, word2, index):
    if index == len(word1):
        return [word1, word2]
    if index == len(word2):
        return [word2, word1]
    if ord(word1[index]) == ord(word2[index]):
        return alphaOrder(word1, word2, index + 1)
    elif ord(word1[index]) < ord(word2[index]):
        return [word1, word2]
    else:
        return [word2, word1]

here is the function i'm trying to make it work with a list of more than 2 elements :

def sortMyList(liste):
    continu = True
    noInversion = False
    i = 0
    while continu:
        item0 = liste[i]
        item1 = liste[i + 1]
        l = alphaOrder(item0, item1, 0)
        if liste[i] != l[0]:
            noInversion = True

        liste[i]   = l[0]
        liste[i+1] = l[1]       
        if i + 1 < len(liste):
            i += 1
        else:
            i = 0


        if noInversion:
            continu = False
    return liste

and here is my test list to verify that my function work or not:

a = []
a.append("aaaazza")
a.append("anaaazza")
a.append("anaaazz11a")
a.append("aaaaa")

print(a)
print(sortMyList(a))

and when i'm printing, this is what i get :

['aaaazza', 'anaaazza', 'anaaazz11a', 'aaaaa']
['aaaazza', 'anaaazz11a', 'anaaazza', 'aaaaa']

but i should get :

['aaaaa', 'aaaazza', 'anaaazz11a', 'anaaazza']

do someone has any idea about what's wrong and what should i correct please ?

3

There are 3 best solutions below

2
On BEST ANSWER

Your problem is that as soon as you find two items that need to be swapped you set noInversion true and exit from the list immediately after switching them.

What you need to do is complete a full pass through the list and only check your flag at the end of the the pass. Also you need to sort out the inversion flag: you want it to start off false, be set true when items are swapped and break the loop at the end if it is still false.

def sortMyList(liste):
    continu = True
    while continu:
        inversion = False
        for i in range(len(liste)-1):
            item0 = liste[i]
            item1 = liste[i + 1]
            l = alphaOrder(item0, item1, 0)
            if liste[i] != l[0]:
                inversion = True

            liste[i]   = l[0]
            liste[i+1] = l[1]       
        if not inversion:
            continu = False
    return liste

Then there's a lot of cleaning up you can do to the code. Using break instead of the continu flag, and collapsing the assignments into the list will help:

def sortMyList(liste):
    while True:
        inversion = False
        for i in range(len(liste)-1):
            item0 = liste[i]
            item1 = liste[i+1]
            liste[i], liste[i+1] = alphaOrder(item0, item1, 0)
            if liste[i] != item0:
                inversion = True

        if not inversion:
            break
    return liste

Still plenty more you can do to improve it, but that should get you started.

3
On

Not sure behind the idea of doing your own function here but you could easily achieve this by simply using the built-in sorted function:

>>> sorted(['aaaazza', 'anaaazza', 'anaaazz11a', 'aaaaa'])
['aaaaa', 'aaaazza', 'anaaazz11a', 'anaaazza']
0
On

This is the final working function :

def sortMyList(liste):
continu = True
inversion = False
i = 0
while continu:
    print("i : " + str(i) + " " + str(liste))
    item0 = liste[i]
    item1 = liste[i + 1]
    print("Comparison between " + item0 + " and " + item1 + " inversion : " + str(inversion))
    l = alphaOrder(item0, item1, 0)
    if liste[i] != l[0]:
        inversion = True
        print("I have to do an inversion : "  + str(inversion)) 
    liste[i]   = l[0]
    liste[i+1] = l[1]               
    if not inversion and i+2 == len(liste):
        continu = False         
    if (i + 2) < len(liste):
        i += 1
    else:
        i = 0
        inversion = False                       
return liste

and the result is :

['aaaaa', 'aaaazza', 'anaaazz11a', 'anaaazza']

I added a lot of prints to see every change in the list and when the inversion was True or False.

Thank you guys for your answers.