85

リストの最初と最後のアイテムのみをスライスする方法はありますか?

例えば; これが私のリストの場合:

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

13 に答える 13

106

一方通行:

some_list[::len(some_list)-1]

より良い方法(スライスを使用しませんが、読みやすくなります):

[some_list[0], some_list[-1]]
于 2012-08-31T15:57:07.387 に答える
29

Python 3の唯一の答えは(スライスを使用したり、残りの部分を破棄したりすることはありませんが、listとにかく十分かもしれません)、アンパックの一般化を使用して中央firstからlast分離します。

first, *_, last = some_list

_引数の「残り」のキャッチオールとしての選択は任意です。_それらは、「私が気にしないもの」の代用としてよく使用される名前で保存されます。

他の多くのソリューションとは異なり、これにより、シーケンスに少なくとも2つの要素が含まれるようになります。1つしかない場合(つまり、同一firstlastなる場合)、例外(ValueError)が発生します。

于 2017-04-17T12:32:42.830 に答える
21

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')
于 2012-08-31T15:59:49.713 に答える
16
first, last = some_list[0], some_list[-1]
于 2012-08-31T15:58:48.527 に答える
9

間違った質問に答えている人もいるようです。あなたはやりたいと言った:

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

しかし、後であなたは複雑さを述べます:「私はそれを同じ行に分割しています、そしてそれはそれを2回分割するのに時間を費やさなければならないでしょう:」

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

したがって、2つのsplit()呼び出しを回避するには、1回の分割の結果であるリストのみを操作する必要があります。

この場合、1行でやりすぎを試みると、明快さと単純さが損なわれます。変数を使用して、分割結果を保持します。

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

リスト内包表記アプローチの利点は、タプル内のインデックスのセットを任意にプログラムで生成できることです。

于 2015-08-29T21:54:31.013 に答える
8

これはどうですか?

>>> first_element, last_element = some_list[0], some_list[-1]
于 2012-08-31T15:58:19.920 に答える
7

あなたはこのようにそれを行うことができます:

some_list[0::len(some_list)-1]
于 2012-08-31T15:56:55.997 に答える
5

あなたは次のようなものを使うことができます

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

本当にスライスを使いたいのなら。これの利点は、インデックスエラーを発生させることができず、長さ1または0のリストでも機能することです。

于 2015-11-03T10:08:33.510 に答える
4

実際、私はそれを理解しました:

In [20]: some_list[::len(some_list) - 1]
Out[20]: ['1', 'F']
于 2012-08-31T15:57:13.227 に答える
4

これは「スライス」ではありませんが、明示的なインデックスを使用しない一般的なソリューションであり、問​​題のシーケンスが匿名であるシナリオで機能します(したがって、同じ行で作成して「スライス」することができます。 2回作成し、2回インデックスを作成します):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保存せずに1回だけ実行します。listlen

itemgetter複数のアイテムの場合tuple、ではなく、が返されることに注意してlistください。したがって、特定の名前にアンパックするだけでなく、trueが必要な場合は、コンストラクターlistで呼び出しをラップする必要があります。list

于 2017-04-17T12:18:03.357 に答える
3

これはどう?

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

Result: ['1', 'F']
于 2021-06-18T16:02:15.950 に答える
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つの数値と上位3つの数値を返す例:

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

#Out[2]
#[1, 2, 3, 8, 9, 10]
于 2017-04-28T14:49:08.957 に答える
0

匿名の場合、split2回に分割しないように、すべての作業を1行で行うという、 「1行」の楽しい新しいアプローチは、式として割り当てを実行するためにセイウチ演算子を使用する:=ことです。これにより、次の両方が可能になります。

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

と:

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

どちらの場合も、基本的に1行で行うのとまったく同じです。

split_str = a.split("-")

次に、次のいずれかでフォローアップします。

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

split_strそれが使用されアクセスされた線を超えて持続するという事実を含みます。かなり醜いですが、技術的にはワンライニングの要件を満たしています。1行が必須であったとしても、解凍解決策よりもお勧めすることはitemgetterありません(名前付き変数を明示的にインデックス付けまたはスライスし、その名前付き変数を2回参照する必要がある非セイウチバージョンを除外します)。

于 2020-02-24T20:48:18.327 に答える