Sorting lists in BGE Python?

Hello there :slight_smile:

I’m currently writing a simple script to allow bots to follow a path of nodes (it’s pretty much a Python version of Mmph’s early logic brick AI). In a section of my script, I’m trying to create a list of all the nodes. Here is my current code:


#As usual:

import GameLogic as gl

cont = gl.getCurrentController()
own = cont.owner
scene = gl.getCurrentScene()
objects = scene.objects

#Building a list of the nodes:

nodelist = []

for i in objects:
    if i.name[0:6] == "OBNode":
        nodelist.append(i)
nodelist.sort()
print nodelist

The only problem with sorting the list. All of my nodes are named Node1, Node2, Node3, etc. I’d like the list to be sorted so that Node1 is the first entry, Node2 the second, etc. When I use sort(), though, I get this console output:

http://lh6.ggpht.com/_v6jTIWQ32go/Snajb3VsLcI/AAAAAAAAAGE/MCZBXV-37LI/Console%20Output.jpg

What am I doing wrong? I tryed using str() to make it forcibly append i to the list as a string, but all that did was give me a different scrambled output.

Any help appreciated.

You can’t sort GameObjects, I did it like this: first got a list of all the names, these are strings and can be sorted. Then replaced those with their object.

obs = gl.getCurrentScene().objects
cont = gl.getCurrentController()
own = cont.owner
own["NodeList"] = []
tempList = []
#need the name for sorting
for i in obs:
	if i.name.startswith("OBNode_"):
		tempList.append(i.name)
tempList.sort()
#then replace the name with gameOb
for i in tempList:
	own["NodeList"].append(obs[i])

Thanks a lot, Sim, that was really helpful. Just one problem; I have 12 nodes in my scene and since Python is reading the names as strings, the sort function assumes that Node10 comes after Node1 and before Node2. (At least I assume that’s what’s happening). Anyone know a fix or work around for this?

Best would be to rename the nodes: Node01, Node02, Node03 etc.

There is a way to convert numbers to have a leading zero:


a = 5
print "five is: "+"%02d" % a

Will print

five is: 05

but it would be messy to use when you are going to have to remove the zero after the sorting.

The number after the 0 is how many character it should be, %03d would make “005”.

Yep, that’s done it. Thank you very much, kind sir :wink:

using list comprehension should be fastest


import GameLogic as gl
sce = gl.getCurrentScene()
cont = gl.getCurrentController()
own = cont.owner

ls = [ob for ob in sce.objects if ob.name.startswith("OBNode_")]
ls.sort(key = lambda ob: ob.name)

own["NodeList"] = ls