Как удалить последний элемент в списке?


155

У меня есть эта программа, которая вычисляет время, необходимое для ответа на конкретный вопрос, и выходит из цикла while, если ответ неверен, но я хочу удалить последнее вычисление, чтобы я мог позвонить, min()и это было не неподходящее время, извините, если это смущает.

from time import time

q = input('What do you want to type? ')
a = ' '
record = []
while a != '':
    start = time()
    a = input('Type: ')
    end = time()
    v = end-start
    record.append(v)
    if a == q:
        print('Time taken to type name: {:.2f}'.format(v))
    else:
        break
for i in record:
    print('{:.2f} seconds.'.format(i))

Ответы:


253

Если я правильно понял вопрос, вы можете использовать нотацию срезов, чтобы сохранить все, кроме последнего элемента:

record = record[:-1]

Но лучший способ - удалить элемент напрямую:

del record[-1]

Примечание 1: Обратите внимание, что использование record = record [: - 1] на самом деле не удаляет последний элемент, а назначает подсписок записи. Это имеет значение, если вы запускаете его внутри функции, а запись является параметром. При record = record [: - 1] исходный список (вне функции) не изменяется, при del record [-1] или record.pop () список изменяется. (как заявил @pltrdy в комментариях)

Примечание 2: в коде могут использоваться некоторые идиомы Python. Я настоятельно рекомендую прочитать это:
Code Like a Pythonista: Idiomatic Python (из архива машины обратного пути).


del record [-1] имеет побочные эффекты. Это плохой дизайн, и его по возможности следует избегать.
Longurimont

@Longurimont, не могли бы вы объяснить, какие у него побочные эффекты?
М. Вольф,

@M. Вольф, это довольно хорошо обсуждается здесь: stackoverflow.com/questions/11520492/… tl: dr. Только проблема может быть в цикле, и у вас будут те же проблемы при любом подходе
TheDavidFactor

@TheDavidFactor я не вижу ничего о del x[-1]там
М. Вольфа

Возможно, я неправильно понял исходный комментарий @Logurimont, но все, что находится внутри скобок, - это просто обозначение фрагментов, поэтому я предположил, что проблема была в del. Использование del было рассмотрено в принятом ответе на вопрос, на который я ссылался. Обозначение фрагментов задокументировано здесь: python-reference.readthedocs.io/en/latest/docs/brackets/…
TheDavidFactor

154

ты должен использовать это

del record[-1]

Проблема с

record = record[:-1]

Это то, что он делает копию списка каждый раз, когда вы удаляете элемент, поэтому не очень эффективно


8
Это лучшее решение, чем принятый ответ.
Джефф Ленч


9

Тебе нужно:

record = record[:-1]

перед forпетлей.

Будет установлен recordтекущий recordсписок, но без последнего элемента. Вы можете, в зависимости от ваших потребностей, перед этим убедиться, что список не пуст.


3
Не могли бы вы также использовать record.pop()? (NB: я новичок в Python)
CodeBeard

2
Да, вы также можете использовать record.pop (). См. Docs.python.org/3.3/tutorial/datastructures.html
себастьян,

2
@CodeBeard, вы могли бы использовать, popно в этом нет необходимости, если вы просто хотите выбросить предмет.
paxdiablo

2
Убедитесь, что вы не назначаете значение, возвращаемое pop (), для записи. В противном случае вы сохраняете последнее значение списка в записи.
Себастьян

1
@paxdiablo и Bastiano9 - спасибо - влияет ли неиспользование возврата на производительность?
CodeBeard


3

Если вы много занимаетесь таймингом, я могу порекомендовать этот небольшой (20 строк) контекстный менеджер:

Тогда ваш код мог бы выглядеть так:

#!/usr/bin/env python
# coding: utf-8

from timer import Timer

if __name__ == '__main__':
    a, record = None, []
    while not a == '':
        with Timer() as t: # everything in the block will be timed
            a = input('Type: ')
        record.append(t.elapsed_s)
    # drop the last item (makes a copy of the list):
    record = record[:-1] 
    # or just delete it:
    # del record[-1]

Для справки, вот содержимое диспетчера контекста таймера полностью:

from timeit import default_timer

class Timer(object):
    """ A timer as a context manager. """

    def __init__(self):
        self.timer = default_timer
        # measures wall clock time, not CPU time!
        # On Unix systems, it corresponds to time.time
        # On Windows systems, it corresponds to time.clock

    def __enter__(self):
        self.start = self.timer() # measure start time
        return self

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self.end = self.timer() # measure end time
        self.elapsed_s = self.end - self.start # elapsed time, in seconds
        self.elapsed_ms = self.elapsed_s * 1000  # elapsed time, in milliseconds

На самом деле это первая программа, которую я написал, но когда я немного познакомлюсь с модулем, я изучу его, спасибо!
Самир

1

Если у вас есть список списков ( tracked_output_sheet в моем случае), в котором вы хотите удалить последний элемент из каждого списка, вы можете использовать следующий код:

interim = []
for x in tracked_output_sheet:interim.append(x[:-1])
tracked_output_sheet= interim
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.