12

I am trying to turn a list of positive numbers into a list of negative numbers with the same value in python 3.3.3

For example turning [1,2,3] into [-1,-2,-3]

I have this code:

xamount=int(input("How much of x is there"))
integeramount=int(input("How much of the integer is there"))
a=1
lista=[]
while(a<=integeramount):
    if(integeramount%a==0):
        lista.extend([a])
    a=a+1
listb=lista
print(listb)
[ -x for x in listb]
print(listb)

This prints two identical lists when I want one to be positive and one to be negative.

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • 2
    Do `listb = [ -x for x in lista ]` as I suggested in my answer. – Anton Sep 26 '14 at 17:33
  • The problem was caused by aliasing the list rather than copying it before modifying. The right way to do it is to use a list comprehension. Both of these are duplicates. – Karl Knechtel Aug 10 '22 at 02:33

7 Answers7

36

The most natural way is to use a list comprehension:

mylist = [ 1, 2, 3, -7]
myneglist = [ -x for x in mylist]
print(myneglist)

Gives

[-1, -2, -3, 7]
Anton
  • 4,411
  • 1
  • 15
  • 18
  • Unfortunately this works when typed into shell, however when put into code it does not work, is there an alternative? –  Sep 25 '14 at 19:37
  • 1
    You are mistaken. Everything that works in the shell works "in code". If you have something that doesn't work and need help, you need to post code that shows what you are trying to do. – Anton Sep 26 '14 at 00:31
  • 4
    @Anton: Do not put the `>>> ` to the code. Otherwise, it must work also with possibly the oldest Python you can find. The only problem could be that it creates the new list. It does not modify the existing one. – pepr Sep 26 '14 at 07:26
  • Thanks @pepr that was the problem –  Sep 26 '14 at 15:59
  • 1
    @pepr, OK, I removed the `>>>`. – Anton Sep 26 '14 at 17:34
  • @Anton: Sorry. The note was meant to SamRob85 :) It is OK to use the interactive Python prefix as even the beginners understand that it is not part of the code written into `.py` file. It just flashed to me that it could be the problem in the SamRob's case. – pepr Sep 26 '14 at 18:49
4

If you want to modify a list in place:

mylist = [ 1, 2, 3, -7]
print(mylist)
for i in range(len(mylist)):
    mylist[i] = -mylist[i]
print(mylist)
Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52
4

You can use the numpy package and do numpy.negative()

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
XTZ
  • 41
  • 2
1

For large list, consider using numpy

import numpy as np

a=np.array([1,2,3,4])

# result as a numpy array
b=-a

# can be casted back to list
c=list(b)
Rémi Baudoux
  • 542
  • 3
  • 16
0

There is also this method:

Little note, this will only work if all numbers start positive. It won't affect 0. If you have negative numbers you don't want changing you need to add the IF statement below.

if num < 0: continue
numbers = [1, 2, 3, 4 ,5]
for num in numbers:
    numbers[num-1] = num - (2*num)

numbers
[-1, -2, -3, -4, -5]
Tom
  • 4,257
  • 6
  • 33
  • 49
0

Use map and lambda to do this, just like a Python pro ;)

mylist = [-2, -1, 0, 1, 2]
mylist = list(map(lambda x: -x if x > 0 else x, mylist))  # Or "lambda x: x*-1"
print(mylist)  # [-2, -1, 0, -1, -2]
0

I was going to offer another solution using map:

>>> from operator import neg
>>> list(map(neg, data))

Although I wanted to see the speed vs just the simple comprehension as well as vs numpy, and while it depends on the length of the list for the native solutions, numpy is the way to go for large datasets:

enter image description here

Code for replicating plot:

import perfplot
import numpy as np
from operator import neg

def list_comp(data): return [ -x for x in data]
def map_neg(data): return list(map(neg, data))
def np_neg(data): return np.negative(data)

perfplot.save(
    "argsort.png",
    setup=lambda n: np.random.rand(n),
    kernels=[list_comp, map_neg, np_neg],
    n_range=[2 ** k for k in range(15)],
    xlabel="len(data)",
)
Jab
  • 26,853
  • 21
  • 75
  • 114