有没有办法只切片列表中的第一个和最后一个项目?
例如;如果这是我的清单:
>>> 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]: []
...
单程:
some_list[::len(some_list)-1]
更好的方法(不使用切片,但更容易阅读):
[some_list[0], some_list[-1]]
更一般情况:从列表的每一端返回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]
你可以使用类似的东西
y[::max(1, len(y)-1)]
如果你真的想用切片。这样做的好处是它不能给出索引错误,也适用于长度为1或0的列表。
另一个python3解决方案使用带有“*”字符的元组解包:
first, *_, last = range(1, 10)
这些都很有趣但是如果你有一个版本号并且你不知道字符串中的任何一个段的大小并且你想要删除最后一个段。像20.0.1.300这样的东西,我想最终得到20.0.1而没有300。到目前为止我有这个:
str('20.0.1.300'.split('.')[:3])
以列表形式返回:
['20', '0', '1']
如何将其恢复为由句点分隔的单个字符串
20.0.1
我发现这可能会这样做:
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)
我以为我会用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'
也就是说,您希望将每个元素中的第一个和最后一个元素提取为单独的变量。
在这种情况下,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是使用列表的第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']
列表推导方法的优点是元组中的索引集可以是任意的并且以编程方式生成。
Python 3只回答(不使用切片或丢弃其余的list
,但可能还是足够好)使用解压缩一般化来将first
和last
从中间分开:
first, *_, last = some_list
选择_
作为争论的“休息”的选择是任意的;它们将被存储在_
这个名称中,它通常用作“我不关心的东西”的替身。
与许多其他解决方案不同,这个解决方案将确保序列中至少有两个元素;如果只有一个(所以first
和last
将是相同的),它将引发异常(ValueError
)。
那这个呢?
>>> first_element, last_element = some_list[0], some_list[-1]
实际上,我只想出来:
In [20]: some_list[::len(some_list) - 1]
Out[20]: ['1', 'F']
这不是一个“切片”,但它是一个不使用显式索引的通用解决方案,适用于所讨论的序列是匿名的场景(因此您可以在同一行上创建和“切片”,无需创建两次并索引两次):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
构造函数中包装调用。