On Aug 3, 2:45 am, gc <gc1...@gmail.com> wrote: > Hi everyone! Longtime lurker, hardly an expert, but I've been using > Python for various projects since 2007 and love it. > > I'm looking for either (A) suggestions on how to do a very common > operation elegantly and Pythonically, or (B) input on whether my > proposal is PEP-able, assuming there's no answer to A. (The proposal > is sort of like the inverse of PEP 3132; I don't think it has been > proposed before, sorry if I missed it.) > > Anyway, I frequently need to initialize several variables to the same > value, as I'm sure many do. Sometimes the value is a constant, often > zero; sometimes it's more particular, such as defaultdict(list). I use > dict() below. > > Target lists using comma separation are great, but they don't work > very well for this task. What I want is something like > > a,b,c,d,e = *dict() > > where * in this context means something like "assign separately to > all." I'm not sure that * would the best sugar for this, but the > normal meaning of * doesn't seem as if it would ever be valid in this > case, and it somehow feels right (to me, anyway). > > Statements fitting the form above would get expanded during parsing to > a sequence of separate assignments (a = dict(); b = dict(); c = dict() > and so forth.) That's all there is to it. Compared to the patterns > below, it's svelte, less copy-paste-y (so it removes an opportunity > for inconsistency, where I remember to change a-d to defaultdict(list) > but forget with e), and it doesn't require me to keep count of the > number of variables I'm initializing. > > This would update section 6.2 of the language reference and require a > small grammar expansion. > > But: Is there already a good way to do this that I just don't know? > Below, I compare four obvious patterns, three of which are correct but > annoying and one of which is incorrect in a way which used to surprise > me when I was starting out. > > # Option 1 (separate lines) > # Verbose and annoying, particularly when the varnames are long and of > irregular length > > a = dict() > b = dict() > c = dict() > d = dict() > e = dict() > > # Option 2 (one line) > # More concise but still pretty annoying, and hard to read (alternates > variables and assignments) > > a = dict(); b = dict(); c = dict(); d = dict(); e = dict() > > # Option 3 (multiple target list: this seems the most Pythonic, and is > normally what I use) > # Concise, separates variables from assignments, but somewhat > annoying; have to change individually and track numbers on both sides. > > a,b,c,d,e = dict(),dict(),dict(),dict(),dict() > > # Option 4 (iterable multiplication) > # Looks better, and if the dict() should be something else, you only > have to change it once, but the extra brackets are ugly and you still > have to keep count of the targets... > > a,b,c,d,e = [dict()] * 5 > > # and it will bite you... > > >>> a[1] = 1 > >>> b > {1: 1} > >>> id(a) == id(b) > > True > > # Gotcha! > > # Other forms of 4 also have this behavior: > > a,b,c,d,e = ({},) * 5>>> a[1] = 1 > >>> b > > {1: 1} > > Alternatively, is there a version of iterable multiplication that > creates new objects rather than just copying the reference? That would > solve part of the problem, though it would still look clunky and you'd > still have to keep count. > > Any thoughts? Thanks!
I hesitate to put this forward, as it smells and is probably considered bad practice, but heh! for char in 'abcdefg' : globals()[ char ] = dict() does what you wanted. Best wishes, John -- -- http://mail.python.org/mailman/listinfo/python-list