Can't modify list elements in a loop Python [d

2018-12-31 15:12发布

问题:

This question already has an answer here:

  • How to modify list entries during for loop? 7 answers

While looping over a list in Python, I was unable to modify the elements without a list comprehension. For reference:

li = [\"spam\", \"eggs\"]
for i in li:
    i = \"foo\"

li
[\"spam\", \"eggs\"]

li = [\"foo\" for i in li]
li 
[\"foo\", \"foo\"]

So, why can\'t I modify elements through a loop in Python? There\'s definitely something I\'m missing, but I don\'t know what. I\'m sure this is a duplicate, but I couldn\'t find a question about this, and if there is a link, that would be more than enough. Thank you in advance!

回答1:

Because the way for i in li works is something like this:

for idx in range(len(li)):
    i = li[idx]
    i = \'foo\'

So if you assign anything to i, it won\'t affect li[idx].

The solution is either what you have proposed, or looping through the indices:

for idx in range(len(li)):
    li[idx] = \'foo\'

or use enumerate:

for idx, item in enumerate(li):
    li[idx] = \'foo\'


回答2:

In fact with list comprehension you are not modifying the list, you are creating a new list and then assigning it to the variable that contained the previous one.

Anyway, when you do for i in li you are getting a copy of each value of li in variable i, you don\'t get the reference to a position in li, so you are not modifying any value in li.

If you want to modify your list you can do it with enumerate:

>>> li = [\"spam\", \"eggs\"]
>>> for i,_ in enumerate(li):
        li[i] = \"foo\"
>>> li
 [\'foo\', \'foo\']

or with xrange (in Python 2.7, use range in python 3):

>>> for i in xrange(len(li)):
        li[i] = \"foo\"
>>> li 
 [\'foo\', \'foo\']

or with the list comprehension you showed in your question.



回答3:

I\'m able to modify a list while looping:

lst = range(10)  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

for i, elem in enumerate(lst):
    lst[i] = 0   // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


回答4:

Maybe using dictionaries might be helpful.

>>> li = {0: \"spam\", 1:\"eggs\"}
    for k, v in li.iteritems():
        li[k] = \"foo\"

>>> li
{0: \'foo\', 1: \'foo\'}


回答5:

for element in li - returns you a copy of element, not the element itself.

Solution for your case would be:

for i in range(len(li)):
    li[i] = \'foo\'