2-D list of strings in python?

Question:

I need a 2D array to store strings of variable length. Numpy can do 2D arrays of strings but you need to pre-declare the length which is a bit of a hassle for the intended purpose. I thought that I can do

x = [['']*rows]*columns

but that does not work as intended, as illustrated by the following snippet

x = [['']*2]*2
print(x)
x[0][0] = 'a'
print(x)

which produces

[['', ''], ['', '']]
[['a', ''], ['a', '']]

However the following works as intended:

x=[['a','b'],['c','d']]
x[0][0]='f'
print(x)

with a result

[['f', 'b'], ['c', 'd']]

Obviously the original definition is triggering some type of a shared memory issue but I am having a hard time wrapping my mind over what is going on and how to work around it. How do I sent up a [rows,columns] array of lists where I can address each [row,column] element?

Asked By: GroovyGeek

||

Answers:

List comprehensions will work, they create unique lists:

rows = 2
cols = 2
x = [['' for c in range(cols) ] for r in range(rows) ] 
print(x)
x[0][0] = 'a'
print(x)

Here’s the output:

[['', ''], ['', '']]
[['a', ''], ['', '']]

The problem with your code:

x = [['']*rows]*columns

is that the internal list only gets created once. That is, the expression ['']*rows is only evaluated once (not per column). The expression yields a single list:

['','']

Then, with the expression [obj] * columns, you are creating a new list, with two (columns) entries, both pointing to the same obj. And so, you are correct, the memory is shared since there is only a single contained obj.

Answered By: Mark
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.