You have two basic problems.
First, diffuse_color
is only the display color used for an object in Solid Viewport shading. You need to actually create a material if you want the color in rendering. Here's green:
matg = bpy.data.materials.new("Green")
matg.use_nodes = True
tree = matg.node_tree
nodes = tree.nodes
bsdf = nodes["Principled BSDF"]
bsdf.inputs["Base Color"].default_value = (0, 1, 0, 0.8)
matg.diffuse_color = (0, 1, 0, 0.8)
(Notice that while I was at it, I gave you a green color instead of a blue one for "Green")
Red would similar:
matr = bpy.data.materials.new("Red")
matg.use_nodes = True
tree = matg.node_tree
nodes = tree.nodes
bsdf = nodes["Principled BSDF"]
bsdf.inputs["Base Color"].default_value = (1, 0, 0, 0.8)
matg.diffuse_color = (1, 0, 0, 0.8)
Second, your assignment loop is OK, except that the mesh copy()
command is linking the mesh of the template object to each of the four new objects, so you only have one mesh. You're setting the color of that mesh by the last entry in your loop and that happens to be red.
There are several ways to duplicate the mesh without linking. It seems like using the duplicate operator would work, but I'll leave it to you to select an appropriate one. But here's how to do it with duplicate
for man in manlist:
bpy.ops.object.duplicate()
ob = bpy.context.active_object
if man['color'] == 'red':
ob.active_material = matr
print('red')
if man['color'] == 'green':
ob.active_material = matg
print('green')
bpy.context.collection.objects.link(ob)
manlist = [ matr, matg, matg, matr]
Then the if statements could be replaced byob.active_material = man
. It makes manlist less readable but the code much shorter. $\endgroup$