jane
jane

Reputation: 385

for line in f: why is there a difference when replacing in lists?

Don't these two say the exact same thing? Why is it when I run the first one, I end up with just the last item in the list, but I get ["a","b","c"] for the second one?

content = ["a\n","b\n","c\n"]

for line in content:
    content = line.replace("\n","")

content = [line.replace("\n","") for line in content]

Upvotes: 0

Views: 97

Answers (5)

Burhan Khalid
Burhan Khalid

Reputation: 174624

In the for loop you are replacing the name content with a string. In effect, the last item from the list content with the \n replaced with '' will be pointed to by the name content.

In the second list comprehension, you are creating a list with each item of the content list with the last character replaced with '' and assigning the new list to the name content.

Upvotes: 5

U2EF1
U2EF1

Reputation: 13259

A fixed version which most closely matches your original:

content = ["a\n","b\n","c\n"]

for i in range(len(content)):
    content[i] = content[i].replace("\n","")
print content

content = ["a\n","b\n","c\n"]
content = [line.replace("\n","") for line in content]
print content

Here the two blocks are equivalent.

Upvotes: 0

chenaren
chenaren

Reputation: 2268

result = [a_func(elem) for elem in a_list]

is equivalent to

result = []
for elem in a_list:
    result.append(a_func(elem))

Therefore, in your example, the for loop equivalent to the list comprehension is

result = []
for line in content:
    result.append(line.replace("\n",""))

Upvotes: 4

jh314
jh314

Reputation: 27792

For the first one, you update content's value with line.replace("\n", ""). This keeps happening for each element in content. Since 'c\n' is the last element, the line has the value 'c\n' at the end of your iteration, and you assign that to content.

#Trace of loop
#iteration 1: line = "a\n"
content = line.replace("\n","") (which is 'a')
#iteration 2: line = "b\n"
content = line.replace("\n","") (which is 'b')
#iteration 3: line = "c\n"
content = line.replace("\n","") (which is 'c')

Thus, content has the value 'c'

The second is a list comprehension, and it means this:

[ "a\n".replace("\n",""), "b\n".replace("\n",""), "c\n".replace("\n","") ]

(I.e. the first element of this new list is line.replace("\n",""), where line takes on the first element of content ("a\n"), and second element of this new list is line.replace("\n",""), where line takes on the second element of content ("a\n"), and so on.)

Upvotes: 1

BrenBarn
BrenBarn

Reputation: 251378

They don't say the same thing. In your first example with the for loop, on every iteration you assign the name content to a single item from the list (line, with some text replaced). content is overwritten every time, so only the last element is there at the end. In the second example, you create an entirely new list and assign that to content.

Upvotes: 1

Related Questions