# Is there a way to select all cameras without iterating through every object in a scene?

I require a way to select certain cameras in a scene. My plan is to get all camera objects in a scene, and then based on their names get the ones that I need.

Currently I’m selecting all cameras like this:

all_cams = [ob for ob in list(bpy.context.scene.objects) if ob.type == ‘CAMERA’]


But i think there should be a better way to do this, without iterating through all objects in a scene. There is the D.cameras collection and from there I can get all data-block names. But how I can go from data-block names to the object name?

Or at least how do I select the cameras using their data-block name? ( then I can work further based on selected objects)

Do you have any ideas how I can achieve this? Thank you!

• Have you identified this operation as a bottleneck in terms of speed ? It should be pretty fast unless you have thousands upon thousands of objects. Otherwise you can use a custom collection property to store camera objects in the scene for instance. Using data block names will be even less efficient because of the lookup : [ob for ob in bpy.context.scene.objects if ob.data.name in camera_names] and even then if 2 cameras use the same data it will fail. Object data don't hold a reference to their object because they can be shared amongst an indefinite number of objects Oct 27 '21 at 7:50
• "Have you identified this operation as a bottleneck in terms of speed ?" Yeah, i was thinking that. Didnt have opportunity to run a test tho. I was just wondering if there is a way to do this. I'll stick to what I have right now, and if it will be a problem I will try to adress it then I guess ;p Oct 27 '21 at 9:03
• Could perhaps get a squeak more with a different test than equality ob.type.startswith('CAM') or via an attribute test hasattr(...) , doubt its worth it. Somewhat related blender.stackexchange.com/a/233823/15543 Oct 27 '21 at 10:42
• Yes there is such a way: [camera for camera in bpy.data.cameras if bpy.context.scene.objects.get(camera.name)]. No guarantee that it will be faster in any given situation though. Nov 1 '21 at 17:22

Don't worry too much, testing all objects in the scene is lightning fast... and the winner is:

[ob for ob in bpy.context.scene.objects if ob.type == 'CAMERA']


Time measurements of a scene with 1000 cameras and 1000 default cubes.

• Code in question

cams = [ob for ob in list(bpy.context.scene.objects) if ob.type == 'CAMERA']
# Time: 0.0026161670684814453

• Regular list comprehension

cams = [ob for ob in bpy.context.scene.objects if ob.type == 'CAMERA']
# Time: 0.0021109580993652344

• Generator

cams = (ob for ob in bpy.context.scene.objects if ob.type == 'CAMERA')
# Time: 6.222724914550781e-05

• Prefix list comprehension

cams = [ob for ob in bpy.context.scene.objects if ob.type.startswith('CAM')]
# Time: 0.0025479793548583984

• Attribute list comprehension

cams = [ob for ob in bpy.context.scene.objects if hasattr(ob.data, "lens")]
# Time: 0.002920866012573242

• The test to me illustrates that they are all almost equal apart from the generator operation which is ~30 times faster. Note that the main issue with generators is that you can only iterate over them once and then they're done. Jan 16 at 17:12