The issue here is that its not always clear when values are wrapped or not, that is to say, when modifying a value will apply changes back to the Blender data the values originally came from.
The rule of thumb here is that array/vector/matrix/quaternion/euler/color types wrap blender internal data, but when you get a single number from any of these types, changes to it won't be applied back to the original data.
Taking Object.scale
as an example...
This will modifiy the objects scale:
obj.scale[0] = obj.scale[0] * 2.0
# or...
obj.scale[0] *= 2.0
# or...
scale = obj.scale
scale[0] *= 2.0
This won't modify the objects scale:
# s is a float and holds no reference to the original data
s = obj.scale[0]
s *= 2.0
# or...
# this does nothing other then to do a multiplication and ignore the result
obj.scale[0] * 2.0
# or...
# by making a copy of the scale, the reference to blender data is dropped,
# this is often useful when you *want* to get some data and manipulate it
# without touching your data in Blender.
scale = obj.scale.copy()
scale[0] *= 2.0
# or...
# by decomposing the scale value by axis,
# we get a list of floats which won't wrap original data,
# this is like '.copy()' but gives us a list rather then a Vector.
scale = [obj.scale[0], obj.scale[1], obj.scale[2]]
scale[0] *= 2.0
# or...
# this also has the effect of returning a new, modified copy.
scale = [s * 2.0 for s in obj.scale]
Note:
While this is a Vector
, the same thing applies to color, eulers... etc as mentioned before.
In the example given in the question, its looping over numbers, so you would have to do something like this...
for i, s in enumerate(obj.scale):
obj.scale[i] = s * 2.0
Note that in this case Vectors can be multiplied by numbers so its best to do:
obj.scale *= 2.0
Note:
if you have a mathutils
class - Vector/Matrix/Color/Quaternion/Euler, you can check to see if they reference some other data with the readonly is_wrapped attribute. You can even get the data they came from using owner