255

I have this program that calculates the time taken to answer a specific question, and quits out of the while loop when answer is incorrect, but i want to delete the last calculation, so i can call min() and it not be the wrong time, sorry if this is confusing.

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))
martineau
  • 119,623
  • 25
  • 170
  • 301
Samir
  • 2,899
  • 4
  • 18
  • 19

8 Answers8

399

If I understood the question correctly, you can use the slicing notation to keep everything except the last item:

record = record[:-1]

But a better way is to delete the item directly:

del record[-1]

Note 1: Note that using record = record[:-1] does not really remove the last element, but assign the sublist to record. This makes a difference if you run it inside a function and record is a parameter. With record = record[:-1] the original list (outside the function) is unchanged, with del record[-1] or record.pop() the list is changed. (as stated by @pltrdy in the comments)

Note 2: The code could use some Python idioms. I highly recommend reading this:
Code Like a Pythonista: Idiomatic Python (via wayback machine archive).

corporateAbaper
  • 428
  • 3
  • 15
sebastian
  • 4,914
  • 2
  • 21
  • 21
  • 2
    del record[-1] has side effects. This is a bad design and should be avoided if possible. – Mountain Man Nov 26 '19 at 22:10
  • 5
    @Longurimont can you please explain what side effects does it have? – M. Volf Sep 13 '20 at 18:51
  • @M. Volf this is pretty well discussed here: https://stackoverflow.com/questions/11520492/difference-between-del-remove-and-pop-on-lists tl:dr only issue might be in a loop and you would have the same issues with any approach – TheDavidFactor Sep 14 '20 at 19:12
  • @TheDavidFactor I don't see anything about `del x[-1]` there – M. Volf Sep 14 '20 at 19:16
  • Maybe I misunderstood @Logurimont's original comment, but anything inside a bracket is simply slice notation so I assumed the issue was with the del. using del was addressed in the accepted answer of the question I referenced. Slice notation is documented here: https://python-reference.readthedocs.io/en/latest/docs/brackets/slicing.html – TheDavidFactor Sep 14 '20 at 19:30
  • @charlie parker setting a variable and popping the last element off the list is not declarative of what the effect you are trying to achieve (deleting the last element, not saving it for use elsewhere), and will typically also end up with an unused variable... – DrCord Dec 10 '20 at 17:13
  • @DrCord what do you mean? It declares you want to remove the last element and then use it...I don't understand your point. – Charlie Parker Dec 12 '20 at 23:43
  • By setting a variable you are saying "I intend to use this". Most modern linters (code hinting) frowns on unused variables because they make your code less clear. Your code should reflect as close to what the intended effect is - you want to remove and discard the element not get and use the element - so `del` is a much better solution. – DrCord Dec 26 '20 at 17:53
183

you should use this

del record[-1]

The problem with

record = record[:-1]

Is that it makes a copy of the list every time you remove an item, so isn't very efficient

John La Rooy
  • 295,403
  • 53
  • 369
  • 502
148

list.pop() removes and returns the last element of the list.

Maciej Gol
  • 15,394
  • 4
  • 33
  • 51
  • 1
    With the mention that it throws an `IndexError` if the list is empty. In case you don't want to have a try/except, there are better options. – Adrian Pop May 13 '22 at 14:16
11

You need:

record = record[:-1]

before the for loop.

This will set record to the current record list but without the last item. You may, depending on your needs, want to ensure the list isn't empty before doing this.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
11

just simply use list.pop() now if you want it the other way use : list.popleft()

Greko2015 GuFn
  • 512
  • 6
  • 13
7

You must use *list,_ = list as in the following example

record = [1,2,3]
*record,_ = record
record
---
[1, 2]
zardilior
  • 2,810
  • 25
  • 30
mon
  • 18,789
  • 22
  • 112
  • 205
3

If you do a lot with timing, I can recommend this little (20 line) context manager:

You code could look like this then:

#!/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]

Just for reference, here's the content of the Timer context manager in full:

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
miku
  • 181,842
  • 47
  • 306
  • 310
  • Actually this is the first 'time' program i've written, but when I get a little more familiar with the module, I'l take a look into it, thank you! – Samir Aug 11 '13 at 08:14
1

If you have a list of lists (tracked_output_sheet in my case), where you want to delete last element from each list, you can use the following code:

interim = []
for x in tracked_output_sheet:interim.append(x[:-1])
tracked_output_sheet= interim
FlyingZebra1
  • 1,285
  • 1
  • 18
  • 28