Python: Removing negatives from a list of numbers

假如想象 提交于 2019-12-01 16:40:12

问题


The question is to remove negatives from numbers.

When remove_negs([1, 2, 3, -3, 6, -1, -3, 1]) is executed, the result is: [1, 2, 3, 6, -3, 1]. The result is suppose to be [1, 2, 3, 6, 3, 1]. what is happening is that if there are two negative numbers in a row (e.g., -1, -3) then the second number will not get removed. def main(): numbers = input("Enter a list of numbers: ") remove_negs(numbers)

def remove_negs(num_list): 
  '''Remove the negative numbers from the list num_list.'''
    for item in num_list: 
        if item < 0: 
           num_list.remove(item) 

    print num_list

main()

回答1:


It's generally a bad idea to remove elements from a list while iterating over it (see the link in my comment for an explanation as to why this is so). A better approach would be to use a list comprehension:

num_list = [item for item in num_list if item >= 0]

Notice that the line above creates a new list and assigns num_list to that. You can also do an "in-place" assignment of the form

num_list[:] = ...

which does not create a new list in memory, but instead modifies the memory location already being pointed to by num_list. This difference is explained in more detail here.




回答2:


Much simpler:

>>> a = [ 1, 2, 3, -3, 6, -1, -3, 1]
>>> [x for x in a if x >= 0 ]
[1, 2, 3, 6, 1]

If you really do want to loop, try this:

def remove_negs(num_list): 
    r = num_list[:]
    for item in num_list: 
        if item < 0: 
           r.remove(item) 
    print r

This does what you want:

>>> remove_negs([ 1, 2, 3, -3, 6, -1, -3, 1])
[1, 2, 3, 6, 1]

The key is that the assignment statement r = num_list[:] makes a copy of num_list. In order not to confuse the loop, We then remove items from r rather than from the list we are looping over.

More: Python's treatment of variables is a bit subtle. Python keeps variable names, like r or num_list separate from variable data, such as [1, 2, 3, 6, 1]. The names are merely pointers to the data. Consider the assignment statement:

r = num_list

After this statement is run, r and num_list both point to the same data. If you make a change to r's data, you are also making a change to num_list's data because they both point to the same data. Now, consider:

r = num_list[:]

This statement tells python to modify num_list's data by taking only certain elements of it. Because of this, python makes a copy of num_list's data. It just so happens that [:] specifies that we want all of num_list's data unchanged but that doesn't stop python from making a copy. The copy is assigned to r. This means that r and mum_list now point to different data. We can make changes to r's data and it doesn't affect num_list's data because they have different data.

If this is new to you, you might want to look at this tutorial about python's approach to variable names and variable data: Understanding Python variables and Memory Management

Examples:

>>> a = [ 1, 2, 3, -3, 6, -1, -3, 1]
>>> b = a   # a and b now point to the same place
>>> b.remove(-1) 
>>> a
[1, 2, 3, -3, 6, -3, 1]

Contrast with:

>>> a = [ 1, 2, 3, -3, 6, -1, -3, 1]
>>> b = a[:] # a and b now point to different data
>>> b
[1, 2, 3, -3, 6, -1, -3, 1]
>>> b.remove(-1)
>>> b
[1, 2, 3, -3, 6, -3, 1]
>>> a
[1, 2, 3, -3, 6, -1, -3, 1]



回答3:


Another solution

filter( lambda x: x>0, [ 1, 2, 3, -3, 6, -1, -3, 1])
[1, 2, 3, 6, 1]



回答4:


From a comment on arshajii's answer:

but that's removing the negative numbers. i need the negative signs removed but still keep the number in the list.

Removing the negative numbers is exactly what your code is clearly trying to do, and it's also the only way to get the desired result:

THe result is suppose to be [1, 2, 3, 6, 3, 1]

But if you really want to "remove the negative signs" from the numbers, that's even easier. For example, to remove the negative sign from -3, you just negate it and get 3, right? You can do this in-place, as in your existing code:

for index, item in enumerate(num_list): 
    if item < 0: 
       num_list[index] = -item

… or in a list comprehension, as in arshajii's:

num_list = [-item if item < 0 else item for item in num_list]

And it's even easier with the abs function, which does exactly that—negates negative numbers, leaves positive and zero alone:

num_list = [abs(item) for item in num_list]

Either way, of course, this will give you [1, 2, 3, 3, 6, 1, 3, 1], which is the wrong answer… but if your comment is correct, it's the answer you asked for.




回答5:


Other the the conventional variable operator non-variable Try some yoda conditions too =)

>>> [i for i in x if 0 <= i]
[1, 2, 3, 6, 1]



回答6:


to strip the numbers off their negative signs, this is the easiest thing to do

def remove_negs(somelist):
    for each in somelist:
        if each < 0:
            somelist[somelist.index(each)] = -each
    print(somelist)

for example

rNegatives([-2,5,11,-1])

prints out

[2,5,11,1]




回答7:


I think an elegant solution can be like this:

import numpy as np

x = [1, 2, 3, -3, 6, -1, -3, 1] # raw data
x = np.array(x) # convert the python list to a numpy array, to enable 
                  matrix operations 
x = x[x >=0] # this section `[x >=0]` produces vector of True and False 
               values, of the same length as the list x
             # as such, this statement `x[x >=0]` produces only the 
               positive values and the zeros

print(x)   
[1 2 3 6 1] # the result


来源:https://stackoverflow.com/questions/20959964/python-removing-negatives-from-a-list-of-numbers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!