Sort 2 lists get index values out

I am trying to make a function “sortListByClass” and just been stuck, like crazy. I’ve been writing and rewriting it forawrds and backwards with no luck.

def sortListByClass(listToSort, NumbersToSortBy):

I have a list that is structured in a specific way
NumbersToSortBy = [‘99’, ‘100’, ‘103’, ‘105’]
listToSort = [‘105’, ‘99’, ‘100’, ‘100’, ‘103’, ‘99’] it keeps going for a while
I need to feed both of them into the function and get index values out
something that would look like this
[1, 5, 2, 3, 4, 0]
I am then going to use this “matrix” to organize 3 other lists by, which I know how to do.

Somehow I am hitting a wall with this one.

After a lot of googling around, I found this

indices = [i for i, x in enumerate(my_list) if x == value]

And I cannot grasp how that is working when I feed it just one value, thus I cannot figure out how to deconstruct it and make it into a loop that works as a function.

Very new to python, any help is appreciated.

If anyone has time for what might be quick to someone who knows what they are doing.
I’m still caught in the weeds. :confused:

I could not follow your example.
You have a listToSort = [‘105’, ‘99’, ‘100’, ‘100’, ‘103’, ‘99’]
and a NumbersToSortBy = [‘99’, ‘100’, ‘103’, ‘105’]
which generate a list of index values [1, 5, 2, 3, 4, 0]
I see there are 6 numbers in the listToSort and 6 in the list of index values so this much I get.
But I am not seeing how the indices get generated using NumbersToSortBy.
Once I see this then maybe I can figure out what to code.

Regards,
Terry.

@Terry_Chappell That is my problem exactly. :joy:
I am trying to generate that but I have yet to figure out how to do so.
I wrote that out by hand as an example of what I need for the function to return.
What I found googling around is

indices = [i for i, x in enumerate(my_list) if x == value]

and If I just manually feed one value into it, say 99, it does sort and give me more then just one index. In this case [1,5]. but I need to to keep looking and building that list.
Does this make sense?

No. I do not understand. Are you saying you have to reverse engineer how the indices [1, 5, 2, 3, 4, 0] were generated from the other 2 lists?

Regards,
Terry.

@Terry_Chappell No I am saying that I want to generate this list.

[1, 5, 2, 3, 4, 0]

Somehow…
I dunno how to generate it.
I just manually typed it out as an example of what I need for the function to return when it’s done.

This is beyond my understanding.

Hi,

On my phone so rather brief.

This can help in finding the index of an item:

I had some more time behnd the laptop:

NumbersToSortBy = ['99','100','103','105']
listToSort = ['105', '99', '100', '100', '103', '99'] 

indices_list = []
for number in listToSort:
    number_index = NumbersToSortBy.index(number)
    indices_list.append(number_index)
    
print indices_list

Does that work as you want it to work?

@Willem Thank you for looking into this.
I the numbers I am getting from that loop are
[3, 0, 1, 1, 2, 0]

But it should be
[1, 5, 2, 3, 4, 0]

Because
99 exist in listToSort in 1st and 5th index
100 exist in listToSort in 2nd and 3rd index
103 exist in listToSort in 4th index
105 exist in listToSort in 0 index

Right now that loop is returning index from NumberstoSortBy, rather then listToSort

Need to find every occurrence of a number in NumbersToSortBy inside of listToSort and get the index from listToSort index

Hope I am explaining things well.

I appreciate your help!

Oh I see I got it wrong. I misunderstood the issue.

Another try from my phone:

indices =[]
for value in listtosort:
indices.extend( [i for i, x in enumerate(NumbersToSortBy) if x == value])

Print indices

Apart from the bad formatting, does this build the list you need?

-Willem

When I tested this it returns:
[[3], [0], [1], [1], [2], [0]]
which is the same as before but with each value in a list. It is not yet the:
[1, 5, 2, 3, 4, 0]
he was looking for.

Regards,
Terry.

Ok,. I’m screwing up here. Wanting to answer to hastily.

I corrected the return of nested lists already.

How about swapping the 2 lists?

I sign off now not wanting to get you guys on another wild goose chase with my hasty replies.

-Willem

Here it is:

NumbersToSortBy = ['99','100','103','105']
listToSort = ['105', '99', '100', '100', '103', '99'] 
indices = []
for num in NumbersToSortBy:
	indices.extend([i for i, x in enumerate(listToSort) if x == num])
print indices

[1, 5, 2, 3, 4, 0]

Mikhail, this uses the hint you found by googling around.
Willem this swaps the two lists as you suggested.

2 Likes

I cannot belive that 3 lines of text got me stuck so damm bad

Terry could you explain how that main line is working? Or point to so articles to read about it?
I want to really wrap my brain around this one, so in the near future I need to do this again, I don’t just blindly copy paste.
Why is there and I before the for statement? And there are no : before then IF statement.
Is there a different way that line can be written, more “traditional” ?

@Terry_Chappell and @Willem thank you so much for your time and help!

The hint you found by googling around uses what is call a list comprehension. A list comprehension returns a list and the arguments inside are: [item-to-add-to-list for-an-item-in-list if-this-condition-is-met]. An additional wrinkle in this case is the enumerate which creates a sequential number to go with each item it takes from the list. So as you get more items from the list it counts up from 0 to length(list)-1. This is just a convenient way to figure out the index into the listToSort while the match is being done.

Another way to write it is:

i = 0
for x in listToSort:
    if x == num:
        indices.append(i)
    i += 1

A list comprehension is a way to get the whole thing down to one line and write less code.

Hope this helps.

Regards,
Terry.

2 Likes

Thank you so much for the solution and a full explanation!
Beginner in code and 1st time trying to do something in python.
Lots and lots to learn!

Thanks once again for your time and your patience!

1 Like