Sort a list of objects by name

Hi,
how do you sort a list of objects by name?

As an example: I have three cubes: Cube.001, Cube.002 and Cube.003.
They are in a list called “mylist” that looks like this:

[bpy.data.objects['Cube.002'], bpy.data.objects['Cube.001'], bpy.data.objects['Cube.003']]

I would like to sort them by name and get the following result:

[bpy.data.objects['Cube.001'], bpy.data.objects['Cube.002'], bpy.data.objects['Cube.003']]

I tried sorting in the following ways:

sorted(mylist)

I get the error

TypeError: unorderable types: Object() < Object()

and

mylist.sort()

which gives me the same error.

So, how can this be done?

Maybe use a dictionary instead and use the objects name as the key?

The list is actually a selection. It is what I get if I say:

bpy.context.selected_objects

Is there a way to transform this into a dictionary or something like that?

Never mind the dictionary, just:


myList = [obj.name for obj in bpy.context.selected_objects]
myList = sorted(myList)

That will give your a sorted list of the objects’ names as strings.

Thank you.
But now the list no longer consists of objects but only of the names.
I would like to access the objects in this list for example like this:

myList[1].scale

objs = bpy.data.objects
objs[myList[1]].scale

I haven’t done much with python in blender, but I would assume that the solution would be the same as a normal python so this is what I would do.

Define a function to return the name of the object.

 def getobjname(obj):
    return obj.name

and then use that function as the key to sort your list:

sorted(mylist, key = getobjname)

Edit:
I remembered the Lambda way to do this:

sorted(mylist, key = lambda obj: obj.name)

look up lambda functions, as they are cool and I may have made a typo. The short explanation of Lambdas is that they are anonymous functions, before the : is the function argument, and after the : is what the function returns. In this case the Lambda take in the obj and returns the obj.name, sorted() then uses what is returned to sort the list of original objects.

a solution that i use is to create a list of lists, first item is the datablock name and the second is the datablock itself;


# selected objects
selectedObjects = [
  # [object.name, object]
]

# objects
for object in context.selected_objects[:]:

  # append selected objects
  selectedObjects.append([object.name, object])

now you can sort this list with;


# sorted selected objects
for datablock in sorted(selectedObjects):

  # print datablock name (example)
  print(datablock[1].name)

When you need the actual api path or datablock just reference datablock[1] to get the second item in your now sorted list of tuples.


import bpy

objs = bpy.context.selected_objects
objs.sort(key = lambda o: o.name)

2 Likes