0

To create a matrix whose values are lists I normally do the following:

T = [[0]*(4) for x in range(4)]
print T

Output:

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

I am trying to create a matrix whose values are dictionaries , I try the same thing and I get problem.

T = [{"first":None,"second":None} *(4) for x in range(4)]

TypeError: unsupported operand type(s) for *: 'dict' and 'int'

What is the correct way to do this?

Intention:

At each T[i][j] , I am trying to record the values picked by first player and second player in a game round (i,j).

KurinchiMalar
  • 598
  • 3
  • 12
  • 28

3 Answers3

1

If I understand you correctly you should write:

T = [[{"first":None,"second":None} for y in range(4)] for x in range(4)]
print T

`

[[{'second': None, 'first': None}, {'second': None, 'first': None},
{'second': None, 'first': None}, {'second': None, 'first': None}],
 [{'second': None, 'first': None}, {'second': None, 'first': None},
 {'second': None, 'first': None}, {'second': None, 'first': None}], 
[{'second': None, 'first': None}, {'second': None, 'first': None}, 
{'second': None, 'first': None}, {'second': None, 'first': None}], 
[{'second': None, 'first': None}, {'second': None, 'first': None},
 {'second': None, 'first': None}, {'second': None, 'first': None}]]`

Reason you can't do:

T = [[{"first":None,"second":None}]*4 for x in range(4)]

is the same as the reason you can't do:

T = [[[1]]*4 for x in range(4)]

When you write * you are essentially repeating the same object given number of times. So, if you update one of the entries all the entries in that row will get updated as they are all the same object.

This doesn't happen in case of : T = [[0]*4 for x in range(4)]

as 0 is an int and you replace it completely when you assign a new value at any place. You can find better explanation in some other SO answers. 1, 2, 3

For dictionaries + and * are not supported. If this answers your problem then you should do more research before posting a question. Otherwise, please elaborate.

Community
  • 1
  • 1
Pukki
  • 586
  • 1
  • 7
  • 18
  • I already tried this. when i try to update.T[0][0]["first"] = 2 T[0][0]["second"] = 3 the entire first list gets updated. which i dont want. I want just the first dic at T[0][0] to get updated. – KurinchiMalar Jan 26 '16 at 05:25
  • Ohh, right my mistake I will update with explanation. – Pukki Jan 26 '16 at 05:27
  • This is exactly what I wanted! Thankyou... Now I am able to reference T[0][0]["first"] = 2 T[0][0]["second"] = 3 T[0][1]["first"] = 4 and get necessary changes – KurinchiMalar Jan 26 '16 at 05:40
0

if you want a dictionary with 4 unique keys you need to have a generator making the keys as well:

EDIT - removed *(4) from copied code

T = [{i:None for i in range(4)} for x in range(4)]

do take note that the keys of a dictionary do not strictly have to be strings, this makes the keys ints so it would work very similarly to any code meant to support the version using lists

Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
0

I feel that the other answers do not give you what you exactly want, which is how to hack on things to make them behave the way you want to.

Since the dict class does not have an imul numeric type to deal with multiplication operation, we can simply create our own class which does that for us.

a = { 'first': None , 'second': None }

class MultDict:
    def __mul__(self, other):
        lst = []
        for i in range(other):
            lst.append(a.copy())
        return lst

x = MultDict()

t = [ x * (4) for i in range(4)]

print(t)

t[0][0]['first']=2
print(t)

Output:

[[{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}],
[{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}],
[{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}],
[{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}]] 


[[{'first': 2, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}],
[{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}],
[{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}],
[{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None},
{'first': None, 'second': None}]]
oxalorg
  • 2,768
  • 1
  • 16
  • 27