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

99

有没有一种方法可以仅切割列表中的第一个和最后一个元素?

例如,如果这是我的列表:

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

6
哈哈,3个答案,在2秒内一模一样,其中一个是你的。经典。 - Aesthete
3
first, last = some_list[0], some_list[-1] 有什么不好的地方? - Matthew Adams
@MatthewAdams 因为我是在同一行分割它,这样就需要花费两倍的时间进行分割:x, y = a.split("-")[0], a.split("-")[-1] - chown
但实际上,无论如何我都要先获取列表的长度,所以我可能最终需要这样做。 - chown
3
就翻译而言,原文意思是作者在代码审查中拒绝使用some_list[0::len(some_list)-1],认为这样太聪明反而不好。 - DSM
2
@chown: 但是,按照你的解决方案,步骤集设置为len-1,你仍然需要再次拆分才能获取长度! - Martijn Pieters
13个回答

4

这不是一个“切片”,但它是一个通用的解决方案,不使用显式索引,并且适用于序列是匿名的情况(因此您可以在同一行上创建和“切片”,而不需要创建两次并索引两次):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,因此如果你不仅仅是将其解包到特定名称中,而且需要一个真正的list,则必须将调用包装在list构造函数中。


1
那真是可爱又相当快速的! - Daria

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的列表中返回前三个和后三个数字的示例:

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

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

0

有趣的新方法来“单行”匿名 split 事物的情况,使您不必再次拆分它,而是可以在一行中完成所有工作,这种方法使用 海象运算符,:=,将赋值作为表达式执行,允许以下两种情况:

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 方案


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接