Python切片列表中的第一个和最后一个元素

时间:2012-08-31 15:54:41

标签: python list slice subscript

有没有办法只对列表中的第一个和最后一个项进行切片?

例如;如果这是我的清单:

>>> 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]: []
...

18 个答案:

答案 0 :(得分:79)

一种方式:

some_list[::len(some_list)-1]

更好的方法(不使用切片,但更容易阅读):

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

答案 1 :(得分:12)

以为我会用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')

答案 2 :(得分:10)

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

答案 3 :(得分:6)

你可以这样做:

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

答案 4 :(得分:6)

似乎有些人正在回答错误的问题。你说你想做:

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

也就是说,您希望将每个元素中的第一个和最后一个元素提取为单独的变量。

在这种情况下,Matthew Adams,pemistahl和katrielalex的答案都是有效的。这只是一个复合作业:

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']

列表推导方法的优点是元组中的索引集可以是任意的并且以编程方式生成。

答案 5 :(得分:5)

Python 3只回答(不会使用切片或丢弃list的其余部分,但可能还是足够好)使用解包通用来获取first和{{ 1}}与中间分开:

last

选择first, *_, last = some_list 作为" rest"争论是任意的;它们将存储在名称_中,该名称通常用作“我不关心的东西的替身”。

与许多其他解决方案不同,这个解决方案将确保序列中至少有两个元素;如果只有一个(_first相同),则会引发异常(last)。

答案 6 :(得分:5)

这个怎么样?

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

答案 7 :(得分:4)

实际上,我只是想出来了:

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

答案 8 :(得分:2)

您可以使用类似

的内容
y[::max(1, len(y)-1)]

如果你真的想使用切片。这样做的好处是它不能给出索引错误,也可以使用长度为1或0的列表。

答案 9 :(得分:2)

更一般情况:从列表的每一端返回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

以及从列表1-10返回底部和前3个数字的示例:

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

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

答案 10 :(得分:1)

这不是&#34;切片&#34;,但它是一个不使用显式索引的通用解决方案,适用于所讨论的序列是匿名的场景(所以你可以在同一行创建和&#34;切片&#34;而不创建两次并索引两次):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)

但如果你要重复使用getter,你可以通过提前创建它来保存重新创建它的工作(并给它一个有用的,自我记录的名字)。

因此,对于您的特定用例,您可以替换:

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

使用:

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

split只有一次,而不会将完整的list存储在len检查或双重索引等的持久名称中。

请注意,多个项目的itemgetter会返回tuple,而不是list,因此,如果您不只是将其解包为特定名称,并且需要一个真实的{{ 1}},你必须在list构造函数中包装调用。

答案 11 :(得分:1)

另一个python3解决方案使用带“ *”字符的元组解包:

first, *_, last = range(1, 10)

答案 12 :(得分:0)

所有这些都很有趣,但是如果您有版本号并且不知道字符串中任何一个段的大小,并且想要删除最后一个段,该怎么办。像20.0.1.300之类的东西,我想以20.0.1结尾,最后没有300。到目前为止,我已经知道了:

str('20.0.1.300'.split('.')[:3])

以列表形式返回:

['20', '0', '1']

如何将其恢复为由句点分隔的单个字符串

20.0.1

答案 13 :(得分:0)

利用打包/拆包运算符将列表中间的内容打包到单个变量中:

>>> l = ['1', 'B', '3', 'D', '5', 'F']
>>> first, *middle, last = l
>>> first
'1'
>>> middle
['B', '3', 'D', '5']
>>> last
'F'
>>> 

或者,如果您想丢弃中间部分:

>>> l = ['1', 'B', '3', 'D', '5', 'F']
>>> first, *_, last = l
>>> first
'1'
>>> last
'F'
>>> 

答案 14 :(得分:0)

一种有趣的新方法可以“匿名”处理一个split匿名案件,这样您就不会将其拆分两次,而是将所有工作全部使用the walrus operator, :=, to perform assignment as an expression进行,两者:

first, last = (split_str := a.split("-"))[0], split_str[-1]

和:

first, last = (split_str := a.split("-"))[::len(split_str)-1]

提醒您,在两种情况下,它实际上完全等同于一行:

split_str = a.split("-")

然后跟进以下其中一项:

first, last = split_str[0], split_str[-1]
first, last = split_str[::len(split_str)-1]

包括split_str持续超出其使用和访问范围的事实。从技术上讲,它只是满足单行代码的要求,同时相当难看。 我永远不会推荐使用unpackingitemgetter解决方案,即使必须使用单行代码(排除明确索引或切片命名变量的非海象版本)并且必须两次引用所述命名变量)。

答案 15 :(得分:0)

这个怎么样?

some_list[:1] + some_list[-1:]

结果:['1', 'F']

答案 16 :(得分:-2)

我发现这可能会这样做:

list[[0,-1]]

答案 17 :(得分:-3)

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

现在只需在函数外部创建一个变量并调用函数:像这样:

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