51

I am trying to dynamically get the first and last element from an array.

So, let us suppose the array has 6 elements.

test = [1,23,4,6,7,8]

If I am trying to get the first and last = 1,8, 23,7 and 4,6. Is there a way to get elements in this order? I looked at a couple of questions Link Link2. I took help of these links and I came up with this prototype..

#!/usr/bin/env python

import numpy

test = [1,23,4,6,7,8]
test1 = numpy.array([1,23,4,6,7,8])
len_test = len(test)
first_list = [0,1,2]
len_first = len(first_list)
second_list = [-1,-2,-3]
len_second = len(second_list)

for a in range(len_first):
        print numpy.array(test)[[first_list[a] , second_list[a]]]
        print test1[[first_list[a], second_list[a]]]

But this prototype won't scale for if you have more than 6 elements. So, I was wondering if there is way to dynamically get the pair of elements.

Thanks!

Mikhail
  • 8,692
  • 8
  • 56
  • 82
pistal
  • 2,310
  • 13
  • 41
  • 65

10 Answers10

168

I ended here, because I googled for "python first and last element of array", and found everything else but this. So here's the answer to the title question:

a = [1,2,3]
a[0] # first element (returns 1)
a[-1] # last element (returns 3)
lenooh
  • 10,364
  • 5
  • 58
  • 49
  • 1
    The general Python problem (non-Numpy solutions) is solved more dramatically in a separate question: http://stackoverflow.com/questions/12218796/python-slice-first-and-last-element-in-list – tripleee Oct 04 '16 at 08:18
28

How about:

In [10]: arr = numpy.array([1,23,4,6,7,8])

In [11]: [(arr[i], arr[-i-1]) for i in range(len(arr) // 2)]
Out[11]: [(1, 8), (23, 7), (4, 6)]

Depending on the size of arr, writing the entire thing in NumPy may be more performant:

In [41]: arr = numpy.array([1,23,4,6,7,8]*100)

In [42]: %timeit [(arr[i], arr[-i-1]) for i in range(len(arr) // 2)]
10000 loops, best of 3: 167 us per loop

In [43]: %timeit numpy.vstack((arr, arr[::-1]))[:,:len(arr)//2]
100000 loops, best of 3: 16.4 us per loop
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • However, will drop an element for arrays with odd number of elements. If you use `(len(arr)+1)//2` instead, you'll capture the middle element as `(middle,middle)` at the end of the results. – isedev Jan 30 '13 at 17:20
  • 1
    @isedev: We don't really know what the OP's requirements are. That said, the two approaches should cover all possibilities. :) – NPE Jan 30 '13 at 17:28
  • @NPE: I would always have even number of elements. So, that should not be a problem – pistal Jan 30 '13 at 17:34
10
arr = np.array([1,2,3,4])
arr[-1] # last element
mehdi_bm
  • 381
  • 1
  • 3
  • 16
5

Using Numpy's fancy indexing:

>>> test
array([ 1, 23,  4,  6,  7,  8])

>>> test[::-1]  # test, reversed
array([ 8,  7,  6,  4, 23,  1])

>>> numpy.vstack([test, test[::-1]])  # stack test and its reverse
array([[ 1, 23,  4,  6,  7,  8],
       [ 8,  7,  6,  4, 23,  1]])

>>> # transpose, then take the first half;
>>> # +1 to cater to odd-length arrays
>>> numpy.vstack([test, test[::-1]]).T[:(len(test) + 1) // 2]
array([[ 1,  8],
       [23,  7],
       [ 4,  6]])

vstack copies the array, but all the other operations are constant-time pointer tricks (including reversal) and hence are very fast.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
3
>>> test = [1,23,4,6,7,8]
>>> from itertools import izip_longest
>>> for e in izip_longest(test, reversed(test)):
    print e


(1, 8)
(23, 7)
(4, 6)
(6, 4)
(7, 23)
(8, 1)

Another option

>>> test = [1,23,4,6,7,8]
>>> start, end = iter(test), reversed(test)
>>> try:
    while True:
        print map(next, [start, end])
except StopIteration:
    pass

[1, 8]
[23, 7]
[4, 6]
[6, 4]
[7, 23]
[8, 1]
Abhijit
  • 62,056
  • 18
  • 131
  • 204
2

You can simply use take method and index of element (Last index can be -1).

arr = np.array([1,2,3])

last = arr.take(-1)
# 3
ozcanyarimdunya
  • 2,324
  • 1
  • 18
  • 21
1

How about this?

>>> import numpy
>>> test1 = numpy.array([1,23,4,6,7,8])
>>> forward = iter(test1)
>>> backward = reversed(test1)
>>> for a in range((len(test1)+1)//2):
...     print forward.next(), backward.next()
... 
1 8
23 7
4 6

The (len(test1)+1)//2 ensures that the middle element of odd length arrays is also returned:

>>> test1 = numpy.array([1,23,4,9,6,7,8]) # additional element '9' in the middle
>>> forward = iter(test1)                                                      
>>> backward = reversed(test1)
>>> for a in range((len(test1)+1)//2):
...     print forward.next(), backward.next()
1 8
23 7
4 6
9 9

Using just len(test1)//2 will drop the middle elemen of odd length arrays.

isedev
  • 18,848
  • 3
  • 60
  • 59
0

This does it. Note that with an odd number of elements the one in the middle won't be included.

test = [1, 23, 4, 6, 7, 8, 5]    
for i in range(len(test)/2):
    print (test[i], test[-1-i])

Output:

(1, 5)
(23, 8)
(4, 7)
ford
  • 10,687
  • 3
  • 47
  • 54
0

How about this:

xs = [1,23,4,6,7,8]
np.array(list(zip(xs[:len(xs)//2], xs[::-1])))

    array([[ 1,  8],
           [23,  7],
           [ 4,  6]])
Sergio Losilla
  • 730
  • 1
  • 5
  • 14
-1

Assuming the list has a even number of elements, you could do:

test = [1,23,4,6,7,8]
test_rest = reversed(test[:len(test)/2])

for n in len(test_rest):
    print [test[n], test_test[n]]
Rui Vieira
  • 5,253
  • 5
  • 42
  • 55