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?
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.
This happens because the loop iterates from first element to last element. Just reverse loop:
for n in reversed(numbers):
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.
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]
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
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
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]
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
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