Nonono.... aaargh.... ugh.
How the hell can you manage to cramp so much problems is so simple things. This is a good example of things you CAN do versus things you should do.
Ok so here its allmost sane. (its ok unless sumeoen asks you to change something or your doing a big production)
First this breaks the dg, you can sometimes get away with this. But in this case your also managing to break the referencability of the scene. Here its partially valid tough but try to traverse names in different fashion such a trough a set. As a general rule if you use setAttr in a expression your doing something wrong (because it does not leverage dg and thus the ONLY trigger you will have is the force time change which can be bad)
putting it inside a proc and calling it is totally unnecessary and just slowing things down. Would be different if you declared the proc global. And just called it directly youd save time compiling it.
random, fine, you can use random but random isnt repeateble (without use of seed) so every time you reuse it it yields different results. Now this can be fine for some stuff but usually its expected that if you show a proeview of something it will be the Same once you do the final render. So use a pseudo random noise instead of rand. Its more sane for production in general.
But yes what id do id map all the lamps to atexture and use that texture to drive the lamps thatway you could even coregraph the light on and off easily. Sorry no maya in fornt of me right now but look at how GI_joe works.