Chris
Chris

Reputation: 1264

How to remove last odd number in a list

I have a list of numbers and I would like to remove the LAST odd number from it. This code works well only when the last odd number is not repeated throughout the list before:

numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 7]
odd_numbers = []

def remove_last_odd(numbers):
    for n in numbers:
        if n % 2 != 0:
            odd_numbers.append(n)    
    numbers.remove(odd_numbers[-1])
    return numbers

So instead of removing the last 7, I end up removing the first occurrence of 7 in my "numbers" list.

Can anyone help?

Upvotes: 2

Views: 1775

Answers (9)

Nikil
Nikil

Reputation: 1

The solution using a For loop without reversing the list by using the index of the last odd number.

def remove_last_odd(numbers):
   has_odd = False
   last_odd = 0

   for num in range(len(numbers)):

      if numbers[num] % 2 == 1:
          has_odd = True
          last_odd =num 

      if has_odd:
          numbers.pop(last_odd)

   return numbers

Upvotes: 0

Yehoshua Kahan
Yehoshua Kahan

Reputation: 1

This is similar to Ness's approach, but I think a little clearer. First I reverse the list, appending each element into first_list.

Then I go through first_list item by item, using a boolean flag to identify (and skip) the first odd number, appending everything else into second_list.

Finally, I reverse second_list, appending its elements into third_list. Done.

def remove_last_odd(numbers):
    found_it = False
    first_list = []
    second_list = []
    third_list = []

    for num in numbers[::-1]:
        first_list.append(num)

    for num in first_list:

        if found_it == False:

            if num % 2 == 0:
                second_list.append(num)
            else:
                found_it = True

        else:
            second_list.append(num)

    for num in second_list[::-1]:
        third_list.append(num)

    return third_list

Upvotes: 0

Thane Plummer
Thane Plummer

Reputation: 10218

Striving for efficiency, here's a solution that doesn't reverse the list or go through it twice.

def remove_last_odd(numbers):
    idx = len(numbers)
    last_odd = False
    while not last_odd and idx > 0:
        idx -= 1
        last_odd = (numbers[idx] % 2 != 0)

    return numbers[0:idx]

Upvotes: 0

Sede
Sede

Reputation: 61225

You can use max with enumerate without reversing the list. max gives you the last index of the number that is odd. and pop takes an optional argument which is the index of the element you want to remove.

def remove_last(numbers):
    numbers.pop(max(i for i, j in enumerate(numbers) if j % 2 != 0))
    return numbers

Upvotes: 0

Sinux
Sinux

Reputation: 1808

numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 7]

_numbers = numbers[::-1]

for i, index in enumerate(_numbers):
    if i % 2 != 0:
        del(_numbers[index])
    break
print _numbers

Upvotes: 0

Daniel
Daniel

Reputation: 42758

Solution without reversing the list:

def remove_last(iterable, condition):
     result = []
     pre = []
     for x in iterable:
        if condition(x):
            result.extend(pre)
            pre = []
        pre.append(x)
    return result + pre[1:]

remove_last([1,5,6,7,8,9,10], lambda x: x&1)
>>> [1, 5, 6, 7, 8, 10]

Upvotes: 1

ozymandias
ozymandias

Reputation: 59

Use pop() instead of remove(). remove() searches for the argument value in the list and takes out the first one it finds. pop() removes the element at the specific index passed in as an argument. You'll need to refactor you're code so that you're locating the index of the last odd number, but then pop() will do as you expect.

Upvotes: 1

Krzysztof Stec
Krzysztof Stec

Reputation: 75

This happens because the loop iterates from first element to last element. Just reverse loop:

for n in reversed(numbers):

Upvotes: 3

Ronen Ness
Ronen Ness

Reputation: 10740

not the most efficient way but will work:

def remove_last_odd(numbers):
    rnumbers = numbers[::-1]
    for n in rnumbers:
        if n % 2 != 0:  
            rnumbers.remove(n)
            break
    return rnumbers[::-1]

basically do this: reverse list, remove first odd number, reverse again and return.

Upvotes: 4

Related Questions