2

I found this in some legacy code.

list_2 = []
for x in map(None, list_1):
    list_2.append(x)

As far as I can tell this code is pointless and produces the same result as

list_2 = list_1

Am I missing something?

I googled it for hours, looked into python docs but could not find an answer to this specific case. P.S. We are converting code from Python 2 to 3.

edit: Values in the list are strings e.g. ['21', '13C', 'A:32A', ''] (some may be empty strings).

Inzen
  • 23
  • 4

2 Answers2

2

This code makes a deep copy of the list instead of copying the pointer to the list. So alterations to list_1 later won't have an effect on list_2.

>>> list_1 = [1,2,3,4] 
>>> list_2 = [] 
>>> for x in map(None, list_1):
...     list_2.append(x)
...  
>>> list_2       
[1, 2, 3, 4] 
>>> list_3 = list_1 
>>> list_1[0] = 9 
>>> list_1 
[9, 2, 3, 4] 
>>> list_2 
[1, 2, 3, 4] 
>>> list_3 
[9, 2, 3, 4] 
>>>
Saskia
  • 1,046
  • 1
  • 7
  • 23
2

The best reference I can find is here:

If function is None, the identity function is assumed;

Which means map(None, xs) essentially makes a lazy, shallow copy of xs. The confusing thing though is that the shallow copy is immediately iterated in a for, so it's unnecessary.

My guess: originally, None was an actual transforming function. They decided they didn't need that transformation any more though (or moved it somewhere else), but left the "skeleton" in place in case they needed to easily reverse the change in the future (although that appears to never have happened). Even that doesn't make perfect sense though, as the whole for loop could have been replaced with a call to list to force the map, but hey, people write weird stuff sometimes.

It is not equivalent to list_2 = list_1 though, since that makes the two references point to the same list. It does however seem to be equivalent to either of

list_2 = list(list_1)
list_2 = list_1[:]

Which make shallow copies of list_1, as mentioned here.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117