-1

To my mind, the following code should simply reconstruct the input list, but instead I get a list of three copies of that list.

outlist = []
inputList = ["input1", "input2", "input3"]
def bar(input, outlist):
    temp = input
    outlist.append(temp)
    return outlist
r1 = [bar(i, outlist) for i in inputList]

but my result

r1
Out[28]: 
[['input1', 'input2', 'input3'],
 ['input1', 'input2', 'input3'],
 ['input1', 'input2', 'input3']]

Here is my I thought this would do:

  1. Create an empty list
  2. For each item in the input list, append that to outlist.
  3. Return the result once it has gone through all three itemps in inputList.

So what am I missing/not understanding here? Why do I get a list of three identical lists, instead of just one of those lists by itself? Sorry if this has been asked before, but if it has, I was unable to find it (probably because I wasn't searching for the right terminology)

EDIT: Sorry if I wasn't clear. My goal is not to create a copy of a list, I just thought it would be a simple example to demonstrate the list of lists result. Please do not mark this as a duplicate of that question, because the list copying is not the subject of the question.

Edit2: My desired output: ['input1', 'input2', 'input3']

In other words, I want to make a list comprehension that iterates over a list, does something with the items in that list, and appends that item to a list which is the output. Here is another example, just to be clear that duplicating the original list is not my point:

outlist = []
inputList = [1, 2, 3]
def bar(input, outlist):
    temp = input + 1
    outlist.append(temp)
    return outlist
r1 = [bar(i, outlist) for i in inputList]


r1
Out[31]: 
[[2, 3, 4], [2, 3, 4], [2, 3, 4]]

desired output:

[2,3,4]

Sorry if I'm being thick here..

Stonecraft
  • 860
  • 1
  • 12
  • 30
  • 5
    `temp = input` doesn't make a copy. See http://nedbatchelder.com/text/names.html. (Not an answer, but it looks like you may be expecting a copy.) – user2357112 Jun 16 '17 at 20:13
  • 2
    `[bar(i, outlist) for i in inputList]` calls `bar` 3 times and puts *all 3 return values, all of which are `outlist`* into a new list, so you get a new list of length 3, all elements of which are the same list. – user2357112 Jun 16 '17 at 20:16
  • I didn't think whether it made a copy should even matter. I thought that with each iteration "input" would have the same value as i, which would be a single one of the strings from inputList. My expectation was that each iteration would only append a single item from inputList. And the second and third iterations would use the list from previous iterations. – Stonecraft Jun 16 '17 at 20:24
  • All that stuff you describe happens, and `outlist` ends up looking like what you want, but the list the list comprehension built isn't `outlist`. – user2357112 Jun 16 '17 at 20:30
  • The list comprehension that would do what you were trying to do is `[x for x in inputList]`. Your `bar` function and manual `outlist` manipulation just replicate functionality the list comprehension already performs. – user2357112 Jun 16 '17 at 20:33
  • Thanks, but as I said, I'm not trying to copy a list, just that I thought that re-making the list would be a simple example. Why isnt the output of the list comp the value of outlist at the end of the last iteration? – Stonecraft Jun 16 '17 at 20:34
  • 1
    The list comprehension is building its own list. That's what list comprehensions do. You give it `outlist` 3 times and it puts `outlist` in the list it's building 3 times. List comprehensions are not intended to pass your function's return value through directly. – user2357112 Jun 16 '17 at 20:37
  • In that case, I would expect the output to be [["input1"],["input"2],["input3"]. Why isnt each iteration only using a single item i from inputList? – Stonecraft Jun 16 '17 at 20:39
  • 1
    See http://nedbatchelder.com/text/names.html. – user2357112 Jun 16 '17 at 20:42
  • Ok thanks, I get it now – Stonecraft Jun 17 '17 at 04:05

1 Answers1

1

EDIT:

In[71]: def bar(item):
   ...:     return item + 1
   ...: 
In[72]: [bar(i) for i in [1, 2, 3]]
Out[72]: [2, 3, 4]

In[73]: [i + 1 for i in [1, 2, 3]]
Out[73]: [2, 3, 4]
G_M
  • 3,342
  • 1
  • 9
  • 23
  • Thanks, but I'm not trying to clone a list, I just thought this would be a simple example demonstrating the behavior that I am wondering about. – Stonecraft Jun 16 '17 at 20:29
  • @Thoughtcraft "To my mind, the following code should simply reconstruct the input list", how else is that supposed to be interpreted? You then go on to describe a three step process of cloning a list... – G_M Jun 16 '17 at 20:34
  • Because "Why do I get a list of three identical lists, instead of just one of those lists by itself? " I was simply stating the expected output of my example. I could make another example that has nothing to do with recreating lists, but why? – Stonecraft Jun 16 '17 at 20:37
  • OK, I added a second example. – Stonecraft Jun 16 '17 at 21:22
  • Yes, between that and what @user2357112 said, I get it now. – Stonecraft Jun 17 '17 at 04:14