cho*_*own 60 python list slice subscript
有没有办法只切片列表中的第一个和最后一个项目?
例如; 如果这是我的清单:
>>> some_list
['1', 'B', '3', 'D', '5', 'F']
Run Code Online (Sandbox Code Playgroud)
我想这样做(显然[0,-1]
是无效的语法):
>>> first_item, last_item = some_list[0,-1]
>>> print first_item
'1'
>>> print last_item
'F'
Run Code Online (Sandbox Code Playgroud)
我试过的一些事情:
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]: []
...
Run Code Online (Sandbox Code Playgroud)
mgi*_*son 87
单程:
some_list[::len(some_list)-1]
Run Code Online (Sandbox Code Playgroud)
更好的方法(不使用切片,但更容易阅读):
[some_list[0], some_list[-1]]
Run Code Online (Sandbox Code Playgroud)
jte*_*ace 14
我以为我会用numpy的花式索引来展示如何做到这一点:
>>> import numpy
>>> some_list = ['1', 'B', '3', 'D', '5', 'F']
>>> numpy.array(some_list)[[0,-1]]
array(['1', 'F'],
dtype='|S1')
Run Code Online (Sandbox Code Playgroud)
请注意,它还支持任意索引位置,该[::len(some_list)-1]
方法不适用于:
>>> numpy.array(some_list)[[0,2,-1]]
array(['1', '3', 'F'],
dtype='|S1')
Run Code Online (Sandbox Code Playgroud)
正如DSM指出的那样,你可以使用itemgetter做类似的事情:
>>> import operator
>>> operator.itemgetter(0, 2, -1)(some_list)
('1', '3', 'F')
Run Code Online (Sandbox Code Playgroud)
似乎有些人正在回答错误的问题.你说你想做的事情:
>>> first_item, last_item = some_list[0,-1]
>>> print first_item
'1'
>>> print last_item
'F'
Run Code Online (Sandbox Code Playgroud)
也就是说,您希望将每个元素中的第一个和最后一个元素提取为单独的变量.
在这种情况下,Matthew Adams,pemistahl和katrielalex的答案都是有效的.这只是一个复合作业:
first_item, last_item = some_list[0], some_list[-1]
Run Code Online (Sandbox Code Playgroud)
但是后来你说了一个复杂的问题:"我把它分成同一行,那就要把时间分成两次:"
x, y = a.split("-")[0], a.split("-")[-1]
Run Code Online (Sandbox Code Playgroud)
因此,为了避免两次split()调用,您必须仅对拆分一次所产生的列表进行操作.
在这种情况下,试图在一行中做太多是对清晰度和简单性的损害.使用变量来保存拆分结果:
lst = a.split("-")
first_item, last_item = lst[0], lst[-1]
Run Code Online (Sandbox Code Playgroud)
其他回答回答了"如何获得新列表,包括列表的第一个和最后一个元素?"的问题.他们可能会受到你的头衔的启发,根据你仔细阅读你的问题,它提到你实际上不想要的切片.
AFAIK是使用列表的第0个和最后一个元素获取新列表的3种方法:
>>> 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']
Run Code Online (Sandbox Code Playgroud)
列表推导方法的优点是元组中的索引集可以是任意的并且以编程方式生成.
Python 3中唯一的答案(不使用切片或扔掉的剩余部分list
,但可能不够好反正)是使用拆包概括获得first
并last
从中间分开:
first, *_, last = some_list
Run Code Online (Sandbox Code Playgroud)
选择_
“全部”作为论点“其余部分”是任意的;它们将以_
通常用作“我不在乎的东西”的代名词的名称存储。
与许多其他解决方案不同,该解决方案将确保序列中至少包含两个元素;如果只有一个(so first
并且last
将是相同的),它将引发一个异常(ValueError
)。
你可以使用类似的东西
y[::max(1, len(y)-1)]
Run Code Online (Sandbox Code Playgroud)
如果你真的想使用切片。这样做的优点是它不会给出索引错误,并且也适用于长度为 1 或 0 的列表。
那这个呢?
>>> first_element, last_element = some_list[0], some_list[-1]
Run Code Online (Sandbox Code Playgroud)
这不是“切片”,但它是一个通用解决方案,不使用显式索引,并且适用于相关序列是匿名的场景(因此您可以在同一行上创建和“切片”,而无需创建两次并索引两次):operator.itemgetter
import operator
# Done once and reused
first_and_last = operator.itemgetter(0, -1)
...
first, last = first_and_last(some_list)
Run Code Online (Sandbox Code Playgroud)
您可以将其内联为(为了from operator import itemgetter
在使用时简洁起见):
first, last = itemgetter(0, -1)(some_list)
Run Code Online (Sandbox Code Playgroud)
但如果您要经常重复使用 getter,则可以通过提前创建一次来节省重新创建它的工作(并给它一个有用的、自记录的名称)。
因此,对于您的特定用例,您可以替换:
x, y = a.split("-")[0], a.split("-")[-1]
Run Code Online (Sandbox Code Playgroud)
和:
x, y = itemgetter(0, -1)(a.split("-"))
Run Code Online (Sandbox Code Playgroud)
并且split
仅一次,而不将完整的内容存储list
在持久名称中以进行len
检查或双索引等。
请注意,itemgetter
对于多个项目,返回 a tuple
,而不是 a list
,因此,如果您不只是将其解压为特定名称,并且需要 true list
,则必须将调用包装在list
构造函数中。