How do I get the last element of a list? - python

How do I get the last element of a list?
Which way is preferred?
alist[-1]
alist[len(alist) - 1]

some_list[-1] is the shortest and most Pythonic.
In fact, you can do much more with this syntax. The some_list[-n] syntax gets the nth-to-last element. So some_list[-1] gets the last element, some_list[-2] gets the second to last, etc, all the way down to some_list[-len(some_list)], which gives you the first element.
You can also set list elements in this way. For instance:
>>> some_list = [1, 2, 3]
>>> some_list[-1] = 5 # Set the last element
>>> some_list[-2] = 3 # Set the second to last element
>>> some_list
[1, 3, 5]
Note that getting a list item by index will raise an IndexError if the expected item doesn't exist. This means that some_list[-1] will raise an exception if some_list is empty, because an empty list can't have a last element.

If your str() or list() objects might end up being empty as so: astr = '' or alist = [], then you might want to use alist[-1:] instead of alist[-1] for object "sameness".
The significance of this is:
alist = []
alist[-1] # will generate an IndexError exception whereas
alist[-1:] # will return an empty list
astr = ''
astr[-1] # will generate an IndexError exception whereas
astr[-1:] # will return an empty str
Where the distinction being made is that returning an empty list object or empty str object is more "last element"-like then an exception object.

You can also do:
last_elem = alist.pop()
It depends on what you want to do with your list because the pop() method will delete the last element.

The simplest way to display last element in python is
>>> list[-1:] # returns indexed value
[3]
>>> list[-1] # returns value
3
there are many other method to achieve such a goal but these are short and sweet to use.

In Python, how do you get the last element of a list?
To just get the last element,
without modifying the list, and
assuming you know the list has a last element (i.e. it is nonempty)
pass -1 to the subscript notation:
>>> a_list = ['zero', 'one', 'two', 'three']
>>> a_list[-1]
'three'
Explanation
Indexes and slices can take negative integers as arguments.
I have modified an example from the documentation to indicate which item in a sequence each index references, in this case, in the string "Python", -1 references the last element, the character, 'n':
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
>>> p = 'Python'
>>> p[-1]
'n'
Assignment via iterable unpacking
This method may unnecessarily materialize a second list for the purposes of just getting the last element, but for the sake of completeness (and since it supports any iterable - not just lists):
>>> *head, last = a_list
>>> last
'three'
The variable name, head is bound to the unnecessary newly created list:
>>> head
['zero', 'one', 'two']
If you intend to do nothing with that list, this would be more apropos:
*_, last = a_list
Or, really, if you know it's a list (or at least accepts subscript notation):
last = a_list[-1]
In a function
A commenter said:
I wish Python had a function for first() and last() like Lisp does... it would get rid of a lot of unnecessary lambda functions.
These would be quite simple to define:
def last(a_list):
return a_list[-1]
def first(a_list):
return a_list[0]
Or use operator.itemgetter:
>>> import operator
>>> last = operator.itemgetter(-1)
>>> first = operator.itemgetter(0)
In either case:
>>> last(a_list)
'three'
>>> first(a_list)
'zero'
Special cases
If you're doing something more complicated, you may find it more performant to get the last element in slightly different ways.
If you're new to programming, you should avoid this section, because it couples otherwise semantically different parts of algorithms together. If you change your algorithm in one place, it may have an unintended impact on another line of code.
I try to provide caveats and conditions as completely as I can, but I may have missed something. Please comment if you think I'm leaving a caveat out.
Slicing
A slice of a list returns a new list - so we can slice from -1 to the end if we are going to want the element in a new list:
>>> a_slice = a_list[-1:]
>>> a_slice
['three']
This has the upside of not failing if the list is empty:
>>> empty_list = []
>>> tail = empty_list[-1:]
>>> if tail:
... do_something(tail)
Whereas attempting to access by index raises an IndexError which would need to be handled:
>>> empty_list[-1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
But again, slicing for this purpose should only be done if you need:
a new list created
and the new list to be empty if the prior list was empty.
for loops
As a feature of Python, there is no inner scoping in a for loop.
If you're performing a complete iteration over the list already, the last element will still be referenced by the variable name assigned in the loop:
>>> def do_something(arg): pass
>>> for item in a_list:
... do_something(item)
...
>>> item
'three'
This is not semantically the last thing in the list. This is semantically the last thing that the name, item, was bound to.
>>> def do_something(arg): raise Exception
>>> for item in a_list:
... do_something(item)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 1, in do_something
Exception
>>> item
'zero'
Thus this should only be used to get the last element if you
are already looping, and
you know the loop will finish (not break or exit due to errors), otherwise it will point to the last element referenced by the loop.
Getting and removing it
We can also mutate our original list by removing and returning the last element:
>>> a_list.pop(-1)
'three'
>>> a_list
['zero', 'one', 'two']
But now the original list is modified.
(-1 is actually the default argument, so list.pop can be used without an index argument):
>>> a_list.pop()
'two'
Only do this if
you know the list has elements in it, or are prepared to handle the exception if it is empty, and
you do intend to remove the last element from the list, treating it like a stack.
These are valid use-cases, but not very common.
Saving the rest of the reverse for later:
I don't know why you'd do it, but for completeness, since reversed returns an iterator (which supports the iterator protocol) you can pass its result to next:
>>> next(reversed([1,2,3]))
3
So it's like doing the reverse of this:
>>> next(iter([1,2,3]))
1
But I can't think of a good reason to do this, unless you'll need the rest of the reverse iterator later, which would probably look more like this:
reverse_iterator = reversed([1,2,3])
last_element = next(reverse_iterator)
use_later = list(reverse_iterator)
and now:
>>> use_later
[2, 1]
>>> last_element
3

To prevent IndexError: list index out of range, use this syntax:
mylist = [1, 2, 3, 4]
# With None as default value:
value = mylist and mylist[-1]
# With specified default value (option 1):
value = mylist and mylist[-1] or 'default'
# With specified default value (option 2):
value = mylist[-1] if mylist else 'default'

lst[-1] is the best approach, but with general iterables, consider more_itertools.last:
Code
import more_itertools as mit
mit.last([0, 1, 2, 3])
# 3
mit.last(iter([1, 2, 3]))
# 3
mit.last([], "some default")
# 'some default'

Another method:
some_list.reverse()
some_list[0]

Here is the solution for your query.
a=["first","second","second from last","last"] # A sample list
print(a[0]) #prints the first item in the list because the index of the list always starts from 0.
print(a[1]) #prints second item in list
print(a[-1]) #prints the last item in the list.
print(a[-2]) #prints the second last item in the list.
Output:
>>> first
>>> second
>>> last
>>> second from last

list[-1] will retrieve the last element of the list without changing the list.
list.pop() will retrieve the last element of the list, but it will mutate/change the original list. Usually, mutating the original list is not recommended.
Alternatively, if, for some reason, you're looking for something less pythonic, you could use list[len(list)-1], assuming the list is not empty.

You can also use the code below, if you do not want to get IndexError when the list is empty.
next(reversed(some_list), None)

Ok, but what about common in almost every language way items[len(items) - 1]? This is IMO the easiest way to get last element, because it does not require anything pythonic knowledge.

Strange that nobody posted this yet:
>>> l = [1, 2, 3]
>>> *x, last_elem = l
>>> last_elem
3
>>>
Just unpack.

You can use ~ operator to get the ith element from end (indexed from 0).
lst=[1,3,5,7,9]
print(lst[~0])

Accessing the last element from the list in Python:
1: Access the last element with negative indexing -1
>> data = ['s','t','a','c','k','o','v','e','r','f','l','o','w']
>> data[-1]
'w'
2. Access the last element with pop() method
>> data = ['s','t','a','c','k','o','v','e','r','f','l','o','w']
>> data.pop()
'w'
However, pop method will remove the last element from the list.

METHOD 1:
L = [8, 23, 45, 12, 78]
print(L[len(L)-1])
METHOD 2:
L = [8, 23, 45, 12, 78]
print(L[-1])
METHOD 3:
L = [8, 23, 45, 12, 78]
L.reverse()
print(L[0])
METHOD 4:
L = [8, 23, 45, 12, 78]
print(L[~0])
METHOD 5:
L = [8, 23, 45, 12, 78]
print(L.pop())
All are outputting 78

To avoid "IndexError: list index out of range", you can use this piece of code.
list_values = [12, 112, 443]
def getLastElement(lst):
if len(lst) == 0:
return 0
else:
return lst[-1]
print(getLastElement(list_values))

Pythonic Way
So lets consider that we have a list a = [1,2,3,4], in Python List can be manipulated to give us part of it or a element of it, using the following command one can easily get the last element.
print(a[-1])

You can also use the length to get the last element:
last_elem = arr[len(arr) - 1]
If the list is empty, you'll get an IndexError exception, but you also get that with arr[-1].

If you use negative numbers, it will start giving you elements from last of the list
Example
lst=[1,3,5,7,9]
print(lst[-1])
Result
9

If you do my_list[-1] this returns the last element of the list. Negative sequence indexes represent positions from the end of the array. Negative indexing means beginning from the end, -1 refers to the last item, -2 refers to the second-last item, etc.

You will just need to take the and put [-1] index. For example:
list=[0,1,2]
last_index=list[-1]
print(last_index)
You will get 2 as the output.

You could use it with next and iter with [::-1]:
>>> a = [1, 2, 3]
>>> next(iter(a[::-1]))
3
>>>

array=[1,2,3,4,5,6,7]
last_element= array[len(array)-1]
last_element
Another simple solution

Couldn't find any answer mentioning this. So adding.
You could try some_list[~0] also.
That's the tilde symbol

Related

Tuples in For Loops - Python [duplicate]

This question already has answers here:
How to change values in a tuple?
(17 answers)
Closed 1 year ago.
I want to subtract 1 from every digit in a tuple using for loop in Python.
I don't understand why my code is returning the original tuple instead of the desired one. Here is the code:
tuple = (3, 2)
for i in tuple:
i -= 1
print(tuple)
Any idea ?
Tuples are immutable objects, that is, you cannot change the elements of the tuple once it is created, if you do want to change them it would be better to use a list.
a = [3, 2]
for i in a:
i -= 1
print(a)
Which gives an output:
[3, 2]
Why didn't it work, even though lists are mutable? And also, why doesn't your original code produce some kind of error, if tuples are really immutable? Well, this becomes more obvious if you write your for each style loop as a simple for:
for index in range(len(a)):
i = a[index]
i -= 1
print(a)
This code is just a more verbose version of your original example, but now the problem is clear - the code never actually changes the elements of the original list. Instead, each iteration of the for loop creates a new variable, i, which takes its value from the correspondinglist element. i -= 1 changes i, not a[index].
Incidentally, that is why there is no error in your original code, even though tuples are supposed to be immutable - the code simply doesn't try to mutate the original tuple at all.
A working example with a list would be something like:
a = [3, 2]
for index in range(len(a)):
a[index] -= 1
print(a)
which can be made more concise in the end by writing:
a = [3, 2]
a = [i - 1 for i in a]
print(a)
As an aside, if you really must take tuples as input and produce tuples as output, you can convert between tuples and lists using the list and tuple functions. This is also why you shouldn't use tuple as your variable name! Doing so will mean that you can't use that tuple function in the same scope as your tuple variable, making things very difficult and potentially confusing for you.
tuple is immutable
my_tuple = (1,2,3)
my_tuple [0] = 3
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
A couple of things going on. A tuple is immutable and you're assigning the value (3, 2) to the type tuple .
tup = (3, 2)
for i in tup:
i -= 1
print(tup)
Outputs:
(3, 2)
However you could do a list comprehension and cast it to tuple to get the expected result.
tup = (3,2)
tup = tuple([i - 1 for i in tup])
print(tup)
Outputs:
(2, 1)
Tuple is immutable.
try this, i think it will help you.
my_tuple = (3, 2)
new_list = []
for i in my_tuple:
i -= 1
new_list.append(i)
new_tuple = tuple(new_list)
print(new_tuple)
A brief introduction to python data structures should help you out here. Here's the gist
tuples are immutable i.e once created you cannot change the contents, you'll need to create a new one - you cannot modify the contents inplace similar to how strings work in python.
list makes sense but in your case it will still not work because you need to update the contents of the list when you do this:
tuple = (3, 2)
for i in tuple:
i -= 1
print(tuple)
you are basically extracting the contents from the tuple and modifying the value but not storing it anywhere. Even if you use a list like this:
list = [3,2]
for i in list:
i -= 1
print(list)
this will still not work as you are modifying a list item (a primitive type - int, string,etc.) which creates a new item but as it's not being stored it gets lost, when you print the list - it remains the same.
What we can do is modify the list as its mutable at runtime and update the contents like this:
list = [3, 2]
for idx, item in enumerate(list):
list[idx] = item - 1
print(list)
I think tuple is a bad variable name for a tuple because it shadows the tuple of Python
Issue is the values assigned to i are integers and integers themselves are not mutable. So even if i changes, the value in tuple does not. In other words, even though i points to the same object as the integer in tuple, when you do in place subtraction, a new integer is formed and i now points to that, different than what tuple has.
However, if you were to put a mutable object and do similar things:
tup = ([1, 2, 3], [4, -12])
for i in tup:
i[1] = 999
print(tup)
You get
([1, 999, 3], [4, 999])

list.append() in python returning null [duplicate]

This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 6 years ago.
What is the actual difference between list1.append() and list1+list2 in python??
Along with this, why the following statement return NULL?
print(list1.append(list2))
{where list1 and list2 are 2 simple list}
list.append() modifies the object and returns None.
[] + [] creates and "returns" new list.
https://docs.python.org/2.7/tutorial/datastructures.html#more-on-lists
Recommended reading: http://docs.python-guide.org/en/latest/writing/gotchas/
Returning None is a way to communicate that an operation is side-effecting -- that is, that it's changing one of its operands, as opposed to leaving them unchanged and returning a new value.
list1.append(list2)
...changes list1, making it a member of this category.
Compare the following two chunks of code:
# in this case, it's obvious that list1 was changed
list1.append(list2)
print list1
...and:
# in this case, you as a reader don't know if list1 was changed,
# unless you already know the semantics of list.append.
print list1.append(list2)
Forbidding the latter (by making it useless) thus enhances the readability of the language.
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a.append(b) # append just appends the variable to the next index and returns None
>>> print a
[1,2,3,[4,5,6]]
>>> a.extend(b) # Extend takes a list as input and extends the main list
[1,2,3,4,5,6]
>>> a+b # + is exactly same as extend
[1,2,3,4,5,6]
When you print a function, you print what it returns and the append method does not return anything. However your list now has a new element. You can print the list to see the changes made.
list1 + list2 means that you combine 2 lists into one big list.
list1.append(element) adds one element to the end of the list.
Here's an example of append vs +
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a + b
[1, 2, 3, 4, 5, 6]
>>>
>>> a.append(b)
>>> a
[1, 2, 3, [4, 5, 6]]

when a python list iteration is and is not a reference

Could someone please offer a concise explanation for the difference between these two Python operations in terms of modifying the list?
demo = ["a", "b", "c"]
for d in demo:
d = ""
print demo
#output: ['a', 'b', 'c']
for c in range(len(demo)):
demo[c] = ""
print demo
#output: ['', '', '']
In other words, why doesn't the first iteration modify the list? Thanks!
The loop variable d is always a reference to an element of the iterable object. The question is not really a matter of when or when isn't it a reference. It is about the assignment operation that you are performing with the loop.
In the first example, you are rebinding the original reference of an element in the object, with another reference to an empty string. This means you don't actually do anything to the value. You just assign a new reference to the symbol.
In the second example, you are performing an indexing operation and assigning a new reference to the value at that index. demo remains the same reference, and you are replacing a value in the container.
The assignment is really the equivalent of: demo.__setitem__(c, "")
a = 'foo'
id(a) # 4313267976
a = 'bar'
id(a) # 4313268016
l = ['foo']
id(l) # 4328132552
l[0] = 'bar'
id(l) # 4328132552
Notice how in the first example, the object id has changed. It is a reference to a new object. In the second one, we index into the list and replace a value in the container, yet the list remains the same object.
In the first example, the variable d can be thought of a copy of the elements inside the list. When doing d = "", you're essentially modifying a copy of whatever's inside the list, which naturally won't change the list.
In the second example, by doing range(len(demo)) and indexing the elements inside the list, you're able to directly access and change the elements inside the list. Therefore, doing demo[c] would modify the list.
If you do want to directly modify a Python list from inside a loop, you could either make a copy out the list and operate on that, or, preferably, use a list comprehension.
So:
>>> demo = ["a", "b", "c"]
>>> test = ["" for item in demo]
>>> print test
["", "", ""]
>>> demo2 = [1, 5, 2, 4]
>>> test = [item for item in demo if item > 3]
>>> print test
[5, 4]
When you do d = <something> you are making the variable d refer to <something>. This way you can use d as if it was <something>. However, if you do d = <something else>, d now points to <something else> and no longer <something> (the = sign is used as the assignment operator). In the case of demo[c] = <something else>, you are assigning <something else> to the (c+1)th item in the list.
One thing to note, however, is that if the item d has self-modifying methods which you want to call, you can do
for d in demo:
d.<some method>()
since the list demo contains those objects (or references to the objects, I don't remember), and thus if those objects are modified, the list is modified too.

Is there a short contains function for lists?

Given a list xs and a value item, how can I check whether xs contains item (i.e., if any of the elements of xs is equal to item)? Is there something like xs.contains(item)?
For performance considerations, see Fastest way to check if a value exists in a list.
Use:
if my_item in some_list:
...
Also, inverse operation:
if my_item not in some_list:
...
It works fine for lists, tuples, sets and dicts (check keys).
Note that this is an O(n) operation in lists and tuples, but an O(1) operation in sets and dicts.
In addition to what other have said, you may also be interested to know that what in does is to call the list.__contains__ method, that you can define on any class you write and can get extremely handy to use python at his full extent.
A dumb use may be:
>>> class ContainsEverything:
def __init__(self):
return None
def __contains__(self, *elem, **k):
return True
>>> a = ContainsEverything()
>>> 3 in a
True
>>> a in a
True
>>> False in a
True
>>> False not in a
False
>>>
I came up with this one liner recently for getting True if a list contains any number of occurrences of an item, or False if it contains no occurrences or nothing at all. Using next(...) gives this a default return value (False) and means it should run significantly faster than running the whole list comprehension.
list_does_contain = next((True for item in list_to_test if item == test_item), False)
The list method index will return -1 if the item is not present, and will return the index of the item in the list if it is present. Alternatively in an if statement you can do the following:
if myItem in list:
#do things
You can also check if an element is not in a list with the following if statement:
if myItem not in list:
#do things
There is also the list method:
[2, 51, 6, 8, 3].__contains__(8)
# Out[33]: True
[2, 51, 6, 3].__contains__(8)
# Out[33]: False
There is one another method that uses index. But I am not sure if this has any fault or not.
list = [5,4,3,1]
try:
list.index(2)
#code for when item is expected to be in the list
print("present")
except:
#code for when item is not expected to be in the list
print("not present")
Output:
not present

How does Python iterate a for loop?

I tried the following code on Python, and this is what I got:
It seems like for many changes I try to make to the iterables by changing elem, it doesn't work.
lis = [1,2,3,4,5]
for elem in lis:
elem = 3
print lis
[1, 2, 3, 4, 5]
However if the iterables are objects with its own methods (like a list), they can be modified in a for loop.
lis = [[1],[2]]
for elem in lis:
elem.append(8)
print lis
[[1, 8], [2, 8]]
In the for loop what exactly is the 'elem' term? Thanks in advance!
The reason that this doesn't work is because you're misunderstanding what elem is. It's not the object itself, and it's not even correct to call it a "variable".
It's a name, kind of like a label, that points to the object. If you just directly assign over it, you're just overwriting the name to point at something else. But, you still have the original reference to the list, so assigning a different value over elem doesn't modify lis itself.
Now, in this case, since all of the objects that elem points to are integers, you can't even change them at all - because integers (and many other types, like strings or tuples) are immutable. That means, simply put, that once the object has been created it cannot be modified. It has nothing to do with whether they "have methods" or not (all Python objects have methods, integers included), but on whether or not they are immutable.
Some objects, however, are mutable, meaning that they can be changed. Lists are examples of such objects. In your second example, elem is a name that references the list objects contained within lis, which themselves are mutable. That is why modifying them in-place (using .append(), or .remove(), etc) works fine.
The elem variable in your for loop is a reference to the current object on each iteration. Changing it won't do anything; it will just change the value of the variable elem and that's going to be changed the next time through the loop anyway. To actually change the value of the element in the list, you need a reference to the list and the index of the element to be changed, and you don't have the latter.
So what you want to do is something like this:
for index, elem in enumerate(lis):
lis[index] = 3
This way you have elem for the element's value and index for the position in the list. It saves you from writing lis[index] constantly to get values, but you must still do so to change elements.
You can also do:
for index in xrange(len(lis)):
lis[index] = 3
However, in most situations this is considered un-Pythonic (among other things, what happens if the list gets longer or shorter while it's being iterated)?
Here, you are actually modifying the list object in your second example. In the first example, you are not modifying the number, you are replacing it. This can be a complicated nuance for new users of Python.
Check this out:
>>> x = 1
>>> id(x)
4351668456
>>> x = 2
>>> id(x)
4351668432
id returns the identifier of the object. As you can see above, the object of x changes both of these times.
>>> y = [1]
>>> id(y)
4353094216
>>> y.append(2)
>>> id(y)
4353094216
Here, I modify the list, so the list is still the original object y.
So, all this means that when you are doing elem = 3, it's not modifying it, it is replacing it. And by now, it's not associated with the list anymore.
This is one of the ways you could do what you are trying to do. This grabs the index and then modifies the list, not the number.
lis = [1,2,3,4,5]
for idx, elem in enumerate(lis):
lis[idx] = 3
print lis
[1, 2, 3, 4, 5]
When you assign a new value to the name elem, you just change the local binding in the for loop. If you want to change the values stored in lis, use map or a list comprehension, like this:
lis = [3 for elem in lis]
You can, however, modify the attributes of elem (or call methods that do so), just like you can on any other value.
In your first example you are trying to modify an integer, and it's inmutable (as strings are).
Python variables should be seen as labels pointing to an object. When you iterate over a list of inmutables, elem points to an inmutable object, not to that position in the list, so you can't modify the original list.
In the second case, elem point to an object that can be modified, so you see the original list changed.
It depends on what the type() of elem is.
In your first case each elem is an int object and it does work to change it. You are changing a temporary object when you say: elem = 3, not the item in the list itself.
In the second case each elem is a list object.

Categories