From: Thomas on 16 May 2010 13:36 Greetings I am having a darn awful time trying to update a matrix: row = dict([(x,0) for x in range(3)]) matrix = dict([(x,row) for x in range(-3,4,1)]) matrix[2][1] += 1 matrix[-1][2] += 1 """ Got: a 1 in all col 1 and 2 {-3: {0: 0, 1: 1, 2: 1}, -2: {0: 0, 1: 1, 2: 1}, -1: {0: 0, 1: 1, 2: 1}, 0: {0: 0, 1: 1, 2: 1}, 1: {0: 0, 1: 1, 2: 1}, 2: {0: 0, 1: 1, 2: 1}, 3: {0: 0, 1: 1, 2: 1}} Expected: a 1 in row 2 col 1 and row -1 col 2 {-3: {0: 0, 1: 0, 2: 0}, -2: {0: 0, 1: 0, 2: 0}, -1: {0: 0, 1: 0, 2: 1}, 0: {0: 0, 1: 0, 2: 0}, 1: {0: 0, 1: 0, 2: 0}, 2: {0: 0, 1: 1, 2: 0}, 3: {0: 0, 1: 0, 2: 0}} """ I must be doing something wrong. Researched and researched. Nothing clicks. From: Chris Rebert on 16 May 2010 13:48 On Sun, May 16, 2010 at 10:36 AM, Thomas wrote:> Greetings > > I am having a darn awful time trying to update a matrix: > > row = dict([(x,0) for x in range(3)]) > matrix = dict([(x,row) for x in range(-3,4,1)]) All the columns refer to the very same row dict (`row` obviously). Python doesn't do any copying unless you explicitly request it. Try: matrix = dict([(x, dict([(x,0) for x in range(3)]) ) for x in range(-3,4,1)]) This way, the row-creation code gets called for each column and thus fresh row dicts are created rather than all just referencing the exact same one row dict. Nested comprehensions may be hard to understand, so you may wish to write it using a function instead: def make_row(): return dict([(x,0) for x in range(3)]) matrix = dict([(x,make_row()) for x in range(-3,4,1)]) See also http://www.python.org/doc/faq/programming/#how-do-i-create-a-multidimensional-list Cheers, Chris -- http://blog.rebertia.com From: superpollo on 16 May 2010 13:51 Thomas ha scritto:> Greetings > > I am having a darn awful time trying to update a matrix: > > row = dict([(x,0) for x in range(3)]) > matrix = dict([(x,row) for x in range(-3,4,1)]) > > matrix[2][1] += 1 > matrix[-1][2] += 1 > > """ > Got: a 1 in all col 1 and 2 > {-3: {0: 0, 1: 1, 2: 1}, > -2: {0: 0, 1: 1, 2: 1}, > -1: {0: 0, 1: 1, 2: 1}, > 0: {0: 0, 1: 1, 2: 1}, > 1: {0: 0, 1: 1, 2: 1}, > 2: {0: 0, 1: 1, 2: 1}, > 3: {0: 0, 1: 1, 2: 1}} > Expected: a 1 in row 2 col 1 and row -1 col 2 > {-3: {0: 0, 1: 0, 2: 0}, > -2: {0: 0, 1: 0, 2: 0}, > -1: {0: 0, 1: 0, 2: 1}, > 0: {0: 0, 1: 0, 2: 0}, > 1: {0: 0, 1: 0, 2: 0}, > 2: {0: 0, 1: 1, 2: 0}, > 3: {0: 0, 1: 0, 2: 0}} > """ > > I must be doing something wrong. Researched and researched. Nothing > clicks. clone the row: >>> row = dict([(x,0) for x in range(3)]) >>> import copy >>> matrix = dict([(x,copy.copy(row)) for x in range(-3,4,1)]) >>> matrix[2][1] += 1 >>> matrix[-1][2] += 1 >>> import pprint >>> pp = pprint.PrettyPrinter() >>> pp.pprint(matrix) {-3: {0: 0, 1: 0, 2: 0}, -2: {0: 0, 1: 0, 2: 0}, -1: {0: 0, 1: 0, 2: 1}, 0: {0: 0, 1: 0, 2: 0}, 1: {0: 0, 1: 0, 2: 0}, 2: {0: 0, 1: 1, 2: 0}, 3: {0: 0, 1: 0, 2: 0}}>>> bye From: Peter Otten on 16 May 2010 13:58 Chris Rebert wrote: > Nested comprehensions may be hard to understand, so you may wish to > write it using a function instead: > > def make_row(): > return dict([(x,0) for x in range(3)]) > > matrix = dict([(x,make_row()) for x in range(-3,4,1)]) Another way to skin the cat: >>> row = dict.fromkeys(range(3), 0) >>> matrix = dict((x, row.copy()) for x in range(-3, 4)) >>> matrix[2][1] += 1 >>> matrix[-1][2] += 1 >>> from pprint import pprint >>> pprint(matrix) {-3: {0: 0, 1: 0, 2: 0}, -2: {0: 0, 1: 0, 2: 0}, -1: {0: 0, 1: 0, 2: 1}, 0: {0: 0, 1: 0, 2: 0}, 1: {0: 0, 1: 0, 2: 0}, 2: {0: 0, 1: 1, 2: 0}, 3: {0: 0, 1: 0, 2: 0}} From: Thomas on 16 May 2010 14:39 Chris Wow, that was a very fast response. Thank you, it works (of course)... Cheers "Chris Rebert" wrote in message news:mailman.264.1274032106.32709.python-list(a)python.org...> On Sun, May 16, 2010 at 10:36 AM, Thomas wrote: >> Greetings >> >> I am having a darn awful time trying to update a matrix: >> >> row = dict([(x,0) for x in range(3)]) >> matrix = dict([(x,row) for x in range(-3,4,1)]) > > All the columns refer to the very same row dict (`row` obviously). > Python doesn't do any copying unless you explicitly request it. > > Try: > matrix = dict([(x, dict([(x,0) for x in range(3)]) ) for x in > range(-3,4,1)]) > > This way, the row-creation code gets called for each column and thus > fresh row dicts are created rather than all just referencing the exact > same one row dict. > Nested comprehensions may be hard to understand, so you may wish to > write it using a function instead: > > def make_row(): > return dict([(x,0) for x in range(3)]) > > matrix = dict([(x,make_row()) for x in range(-3,4,1)]) > > See also > http://www.python.org/doc/faq/programming/#how-do-i-create-a-multidimensional-list > > Cheers, > Chris > -- > http://blog.rebertia.com