Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flattening a Python list without creating copies of any objects? [duplicate]

So I'm writing a game in Python, and a problem I'm trying to solve requires that I turn a 2D list (that is, a list of lists) into a 1D list. I've seen several ways to do this, but I don't know if any of them create copies of any objects held within or just new references. To be honest, the Python standard library confuses me in that it's not always obvious whether objects/sequences are copied or just filled with references.

These are the assumptions about my particular situation;

  • We can assume that my 2D list, if represented as a matrix, is perfectly rectangular.
  • It'd be nice if I could have a solution for which the above assumption isn't true, but it's not required at the moment.
  • No need to worry about 3D+ lists.

Thanks!

like image 605
JesseTG Avatar asked Dec 12 '25 17:12

JesseTG


2 Answers

While I can't speak for every way you might have seen, in general no copies will be made due to Python's object semantics.

>>> a = [[1,2.3,'3', object()], [None, [2,3], 4j]]
>>> b = [v for row in a for v in row]
>>> a
[[1, 2.3, '3', <object object at 0x1002af090>], [None, [2, 3], 4j]]
>>> b
[1, 2.3, '3', <object object at 0x1002af090>, None, [2, 3], 4j]
>>> [id(obj) for row in a for obj in row]
[4298185464, 4298195480, 4299558664, 4297781392, 4296523616, 4299692656, 4297773296]
>>> [id(obj) for obj in b]
[4298185464, 4298195480, 4299558664, 4297781392, 4296523616, 4299692656, 4297773296]

That v doesn't mean "some new object equal to v", it simply means v, the object itself.

like image 164
DSM Avatar answered Dec 14 '25 06:12

DSM


Regarding to your question about copies/references, Python operates with mutable/immutable variables in different ways: for immutable variables (int,float,string,tuples etc) you will get copies, for mutable (everything else) - "references".

Regarding flattening of python list: look at itertools module. You can do something like this:

>>> from itertools import chain
>>> chain(*[[1,2,3], [4,5,6], [7,8,9]])
<itertools.chain object at 0x104ff5110>
>>> list(_)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
like image 38
Alexey Kachayev Avatar answered Dec 14 '25 07:12

Alexey Kachayev