Как удалить первое вхождение определенного элемента из списка элементов без использования .pop () или .remove () - PullRequest
1 голос
/ 22 октября 2019

У меня есть список, назовем его l = [1,2,3,7,8,9,10,7]. Учитывая этот список l, я пытаюсь удалить первое вхождение числа 7 без использования встроенных функций .pop () или .remove ().

Я пытался

def remove_item(l, item_to_remove):
  newlst = []
  for item in l:
      if item != item_to_remove:
        newlst.append(item)
  return newlst

Однако при этом удаляются все экземпляры элемента, который я пытаюсь удалить, когда на самом деле я хочу удалить только самый первый экземпляр этого указанного конкретного элемента. У кого-нибудь есть советы о том, как этого добиться ??

Ответы [ 7 ]

5 голосов
/ 22 октября 2019

Вам нужно только позаботиться о том, чтобы удаляющая часть вашего кода не запускалась дважды.

lst = [1,2,3,7,8,9,10,7]  # [1, 2, 3, 7, 8, 9, 10, 7]
print(lst)
for i in range(len(lst)):
    if lst[i] == 7:
        del lst[i]  # [1, 2, 3, 8, 9, 10, 7]
        break
print(lst)

Она работает точно так же, как указано ниже:

lst = [1,2,3,7,8,9,10,7]
print(lst)  # [1, 2, 3, 7, 8, 9, 10, 7]
for i in range(len(lst)):
    if lst[i] == 7:
        lst.pop(i)
        break
print(lst)  # [1, 2, 3, 8, 9, 10, 7]

кака также это

lst = [1,2,3,7,8,9,10,7]
print(lst)  # [1, 2, 3, 7, 8, 9, 10, 7]
for i in range(len(lst)):
    if lst[i] == 7:
        lst.remove(lst[i])
        break
print(lst)  # [1, 2, 3, 8, 9, 10, 7]

Обзор используемых методов:

  1. del list [i] - Оператор del также можно использовать для удаления фрагментов изсписок
  2. list.pop - удалить и вернуть элемент по индексу (последний по умолчанию). Вызывает IndexError, если список пуст или индекс выходит за пределы диапазона.
  3. list.remove - удалить первое вхождение значения. Возникает ValueError, если значение отсутствует.
2 голосов
/ 22 октября 2019

Очень расточительно, но здесь вы идете, решение:

def remove_first(sequence, element):
    return sequence[:sequence.index(element)] + sequence[sequence.index(element)+1:]

Тогда вы можете:

>>> remove_first(["a", "b", "a", "c"], "a"):
['b', 'a', 'c']

index возвращает индекс первого найденного вхождения элемента,Остальное - это объединение последовательностей и их объединение.

Конечно, вы можете обобщить это до remove(sequence, element, n), чтобы удалить n-й найденный элемент. РЕДАКТИРОВАТЬ: Я только что заявил, что index также поддерживает это. Оператор удален.

Или вы можете изменить вид входа, но возвращение результата будет чище, и у вас не будет общего аргумента «последовательность», так как не все последовательности являются изменяемыми. См. tuple тип.

2 голосов
/ 22 октября 2019

.index(x) возвращает первое местоположение индекса x в списке, поэтому просто удалите его. Если x не найдено, возвращается ValueError.

my_list = [1, 2, 3, 7, 8, 9, 10, 7]
val = 7

if val in my_list:
    del my_list[my_list.index(val)]

>>> my_list
[1, 2, 3, 8, 9, 10, 7]

Подпись: my_list.index (значение, начало = 0, стоп = 9223372036854775807, /)

Строка документа: возвращает первый индекс значения.

Повышает значение ValueError, если значение отсутствует.

1 голос
/ 22 октября 2019

Аналогично решению CEWeinhauer , но оно использует преимущества возможностей Python для минимизации накладных расходов после того, как мы нашли удаляемый элемент:

def remove_item(l, item_to_remove):
    newlst = []
    liter = iter(l)                 # Make single pass iterator, producing each item once
    for item in liter:
        if item == item_to_remove:  # Found single item to remove, we're done
            break
        newlst.append(item)         # Not found yet
    newlst += liter                 # Quickly consume all elements after removed item without tests
    return newlst

Вышеприведенное работает с любой ввод, повторяемый за один проход, поэтому лучше, если ввод не будет list и / или может быть огромным. Но это по общему признанию более сложный код. Гораздо более простое решение - просто найти элемент с index и удалить его. В некоторых случаях он может быть немного медленнее, так как вместо одного шага два шага O(n), но он использует больше встроенных Си, поэтому на практике он будет быстрее:

 def remove_item(l, item_to_remove):
     newlst = list(l)
     del newlst[newlst.index(item_to_remove)]
     return newlst
1 голос
/ 22 октября 2019
lst = [1,2,3,7,8,9,10,7]
new_lst = lst[:lst.index(7)] + lst[lst.index(7) + 1:]
new_lst

[1, 2, 3, 8, 9, 10, 7]

1 голос
/ 22 октября 2019

Добро пожаловать в StackOverflow!

Незначительные изменения в вашем коде.

Я бы предпочел remove, но вот ваш модифицированный код для выполнения необходимой работы

def remove_item(l, item_to_remove):
  newlst = []
  for item in l:
      if item != item_to_remove:
        newlst.append(item)
      else:
        return newlst + l[len(newlst) + 1 :]
  return newlst

В Python вы можете добавлять списки. Используя списки, вы выбираете подсписки (l[len(newlst) + 1 :]).

Тестирование

>>> list = [1,3,4,5,6,7,3,10]
>>> print(remove_item(list, 3))
[1, 4, 5, 6, 7, 3, 10]
1 голос
/ 22 октября 2019

Вам просто нужно добавить немного логики. Я добавляю переменную для поиска, которая означает, что мы не нашли запись, которую искали. Вот код

def remove_item(l, item_to_remove):
newlst = []
looking = True
for item in l:
    if item != item_to_remove or not looking:
        newlst.append(item)
    else:
        looking = False

return newlst

list = [1,3,4,5,6,7,3,10]
print(remove_item(list, 3))

, который возвращает [1, 4, 5, 6, 7, 3, 10]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...