Python slice первый и последний элемент в списке

есть ли способ разрезать только первый и последний элемент в списке?

например, если это мой список:

>>> some_list
['1', 'B', '3', 'D', '5', 'F']

Я хочу чтобы сделать это (очевидно [0,-1] недопустимый синтаксис):

>>> first_item, last_item = some_list[0,-1]
>>> print first_item
'1'
>>> print last_item
'F'

некоторые вещи, которые я пробовал:

In [3]: some_list[::-1]
Out[3]: ['F', '5', 'D', '3', 'B', '1']

In [4]: some_list[-1:1:-1]
Out[4]: ['F', '5', 'D', '3']

In [5]: some_list[0:-1:-1]
Out[5]: []
...

13 ответов


одним из способов:

some_list[::len(some_list)-1]

лучший способ (не использует нарезку, но легче читать):

[some_list[0], some_list[-1]]

просто подумал, что я покажу, как это сделать с помощью фантазии индексирования numpy:

>>> import numpy
>>> some_list = ['1', 'B', '3', 'D', '5', 'F']
>>> numpy.array(some_list)[[0,-1]]
array(['1', 'F'], 
      dtype='|S1')

обратите внимание, что он также поддерживает произвольные места индекс, который [::len(some_list)-1] метод не будет работать на:

>>> numpy.array(some_list)[[0,2,-1]]
array(['1', '3', 'F'], 
      dtype='|S1')

как указывает DSM, вы можете сделать что-то подобное с itemgetter:

>>> import operator
>>> operator.itemgetter(0, 2, -1)(some_list)
('1', '3', 'F')

first, last = some_list[0], some_list[-1]

вы можете сделать это так:

some_list[0::len(some_list)-1]

кажется, некоторые люди отвечают на неправильный вопрос. Вы сказали, что хотите сделать:

>>> first_item, last_item = some_list[0,-1]
>>> print first_item
'1'
>>> print last_item
'F'

Ie. вы хотите выделить первый и последний элементы в отдельные переменные.

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

first_item, last_item = some_list[0], some_list[-1]

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

x, y = a.split("-")[0], a.split("-")[-1]

поэтому, чтобы избежать двух вызовов split (), вы должны работать только со списком, который является результатом разделения один раз.

в этом случае попытка сделать слишком много в одной строке наносит ущерб ясности и простоте. Используйте переменную для удержания результата разделения:

lst = a.split("-")
first_item, last_item = lst[0], lst[-1]

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

AFAIK - это 3 способа получить новый список с 0-м и последним элементами списка:

>>> s = 'Python ver. 3.4'
>>> a = s.split()
>>> a
['Python', 'ver.', '3.4']

>>> [ a[0], a[-1] ]        # mentioned above
['Python', '3.4']

>>> a[::len(a)-1]          # also mentioned above
['Python', '3.4']

>>> [ a[e] for e in (0,-1) ] # list comprehension, nobody mentioned?
['Python', '3.4']

# Or, if you insist on doing it in one line:
>>> [ s.split()[e] for e in (0,-1) ]
['Python', '3.4']

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


Как насчет этого?

>>> first_element, last_element = some_list[0], some_list[-1]

Python 3 Только ответ (который не использует нарезку или выбрасывает остальную часть list, но может быть достаточно хорошо в любом случае) использует распаковку обобщений, чтобы получить first и last отделить от середины:

first, *_, last = some_list

выбор _ поскольку уловка для" остальных " аргументов произвольна; они будут сохранены в имени _ который часто используется в качестве дублера для "вещи, о которых я не забочусь".

в отличие от многих других решений, это убедитесь, что в последовательности есть хотя бы два элемента; если есть только один (so first и last будет идентичным), это вызовет исключение (ValueError).


на самом деле, я только что понял:

In [20]: some_list[::len(some_list) - 1]
Out[20]: ['1', 'F']

вы можете использовать что-то вроде

y[::max(1, len(y)-1)]

Если вы действительно хотите использовать нарезки. Преимущество этого заключается в том, что он не может давать ошибки индекса и работает с списками длины 1 или 0.


это не "срез", но это общее решение, которое не использует явное индексирование и работает для сценария, где рассматриваемая последовательность анонимна (поэтому вы можете создавать и "срезать" на одной строке, не создавая дважды и индексируя дважды):operator.itemgetter

import operator

# Done once and reused
first_and_last = operator.itemgetter(0, -1)

...

first, last = first_and_last(some_list)

вы можете просто встроить его как (после from operator import itemgetter для краткости во время использования):

first, last = itemgetter(0, -1)(some_list)

а если вы будете повторно использовать геттер много, вы можете сохранить работу по воссозданию он (и дать ему полезно, самодокументируемыми имя), создав это один раз раньше времени.

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

x, y = a.split("-")[0], a.split("-")[-1]

С:

x, y = itemgetter(0, -1)(a.split("-"))

и split только один раз без сохранения полного list в постоянном имени для len проверка или двойная индексация или тому подобное.

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


более общий случай: возврат N точек с каждого конца списка

ответы работают для конкретного первого и последнего, но некоторые, как и я, могут искать решение, которое можно применить к более общему случаю, в котором вы можете вернуть верхние N точек с любой стороны списка (скажем, у вас есть отсортированный список и хотите только 5 самых высоких или самых низких), я придумал следующее решение:

In [1]
def GetWings(inlist,winglen):
    if len(inlist)<=winglen*2:
        outlist=inlist
    else:
        outlist=list(inlist[:winglen])
        outlist.extend(list(inlist[-winglen:]))
    return outlist

и пример для возврата нижнего и верхнего 3 цифры из списка 1-10:

In [2]
GetWings([1,2,3,4,5,6,7,8,9,10],3)

#Out[2]
#[1, 2, 3, 8, 9, 10]

Я обнаружил, что это может сделать это:

list[[0,-1]]

def recall(x): 
    num1 = x[-4:]
    num2 = x[::-1]
    num3 = num2[-4:]
    num4 = [num3, num1]
    return num4

теперь просто сделайте переменную вне функции и вспомните функцию: вот так:

avg = recall("idreesjaneqand") 
print(avg)