Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
277 views
in Technique[技术] by (71.8m points)

python 3: lists dont change their values

So I am trying to change a bunch of list items by a random percentage using a for loop.

import random as rdm
list = [1000, 100, 50, 25]
def change():
    for item in list:
        item = item + item*rdm.uniform(-10, 10)
change()
print(list)

(also I dont get how to paste multiple lines of code so I did them one by one, would appreciate help with that too) And now when it prints the list it only consists of the numbers it started with.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your item =.... line, as it stands, just associates a new object with the name item in the function's namespace. There is no reason why this operation would change the content of the list object from which the previous value of item was extracted.

Here is a listing that changes a list in-place:

import random
lyst = [1000,100,50,25]
def change(lyst):
    for i, item in enumerate(lyst):
        item = item + item * random.uniform(-10, 10)
        lyst[i] = item

print(lyst)
change(lyst)
print(lyst)

The lyst[i] =... assignment is the key line that actually changes the list's content. Of course you can collapse the two assignments into one line if you want: lyst[i] = item =..... Or you can omit the reassignment to item if you're not going to use it again in the loop: lyst[i] = item + item *...

Note that I performed two minor fixes in addition: I changed the variable name from list to lyst so that it doesn't overshadow your builtin reference to the list class. I have also altered your function so that it takes the list object as an argument, rather than relying on referring to it using a hard-coded global variable name. Both of these are just good practice; nothing to do with your problem.

Finally, note that you can do all of this much more succinctly and transparently with a so-called list comprehension. If you don't have to modify the list in-place, i.e. if it's OK to end up with a modified copy of the original list:

lyst = [ item + item * random.uniform(-10, 10)  for item in lyst ]

If you need to modify the list in-place (e.g. if other references to the original list exist elsewhere and they, too, should point to the updated content after change() is called) then you can follow the suggestion in Padraic's comment:

lyst[:] = [ item + item * random.uniform(-10, 10)  for item in lyst ]

In that last case, you can even save memory (which will only be a concern for very large lists) if you change the bracket shape and thereby use a generator expression instead:

lyst[:] = ( item + item * random.uniform(-10, 10)  for item in lyst )

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...