Multiply each list item by a number

I would like to multiply all list items by a number. I know other ways to do this, but I want to know why this is not working? I get the same list as the output.

lst = eval(input('enter a list')) for num in lst: num = num * 2 print(lst) 
+5
source share
7 answers

It does not work because you use the for loop in the list and define / modify the global variable num , not the elements in the lst list.

For instance:

 >>> l = [1, 5, 8] >>> for num in l: ... num *= 2 ... ... >>> num 16 >>> l [1, 5, 8] 

In this case, in the first loop, num is 1 (the first element in l ), and 1 * 2 is necessarily 2 .

Then num will become 5 , since 5 is the second item in the list. After num * 2 , num will become 10 .

In the second for loop, it becomes 8 * 2 , 16 . it does not change again because the for loop is complete.

However, in this loop you did not change anything in the list. Since for only gets the items in the list and puts it in a temporary variable.

And when you change this temporary variable inside the for loop, you don't change anything in the list.

+6
source

Well, since you wrote "I know other ways to do this, but I want to know why this does not work?" . Here is your answer: you only modify the time loop of the variable num , not the list itself. Try the following:

 for i, num in enumerate(lst): lst[i] = lst[i] * 2 
+4
source

You do not change the lst elements, follow these steps:

 for num in range(len(lst)): lst[num] *= 2 
+4
source
 lst=eval(input('enter a list')) lst=list(map(lambda num:num*2,lst)) print (lst) 

You need to update lst.

+3
source

Better to use ast.literal_eval and then eval because of security. You can read about it here . You can solve this with a list comprehension :

 import ast lst = ast.literal_eval(input('enter a list')) lst = [num*2 for num in lst] print(lst) 

List enumerations are faster than map with lambda . Timing

 lst = list(range(1000)) In [56]: %timeit list(map(lambda num:num*2,lst)) 10000 loops, best of 3: 169 us per loop In [57]: %timeit [num*2 for num in lst] 10000 loops, best of 3: 80.5 us per loop 
+3
source

Two pure expressions:

 In [360]: lst=list(range(10)) 

change place in place:

 In [361]: for i,v in enumerate(lst): .....: lst[i]=v*2 .....: In [362]: lst Out[362]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 

to create a new list:

 In [363]: [v*2 for v in lst] Out[363]: [0, 4, 8, 12, 16, 20, 24, 28, 32, 36] 

For input, I would prefer to explicitly split and convert the string:

 In [365]: lst = [int(x) for x in input().split()] 10 11 0 1 2 In [366]: lst Out[366]: [10, 11, 0, 1, 2] 
+3
source

As everyone else pointed out, the correct way to do this is by indexing into a list:

 myList = range(5) for i in range(len(myList)): myList[i] *= 2 print myList #[0,2,4,..] 

A bit about the passage to the destination

Your loop that uses the for num in list notation does not change the list. Since the num loop variable takes an int value at each iteration of the loop, since ints are immutable (that is, its value cannot be changed) in python, num gets a copy of the integer value.

This changes when the object in the list is modified and passed by reference . Consider the following:

 class X: def __init__(self): self.val = 1 myList = [X() for i in range(5)] print [element.val for element in myList] #1,1,1,1,1 for el in myList: el.val = 2 print [element.val for element in myList] #2,2,2,2,2 

Now, since myList contains a list of X objects that are being modified, the loop variable el has a link copied to it. The link points to the same object in memory that the link points to in the source myList. Therefore, when you change an object using a loop variable, the objects mentioned in the original myList also change.

This Pass By Reference talks about this in more detail.

+2
source

Source: https://habr.com/ru/post/1242836/


All Articles