web-dev-qa-db-ja.com

Pythonリストの最初と最後の要素をスライスします

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

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

>>> some_list
['1', 'B', '3', 'D', '5', 'F']

I wantこれを行うには(明らかに[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]: []
...
58
chown

一方通行:

some_list[::len(some_list)-1]

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

[some_list[0], some_list[-1]]
84
mgilson

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')
12
jterrace
first, last = some_list[0], some_list[-1]
10
Katriel

Python 3の答えは(スライシングを使用せず、listの残りを破棄しますが、とにかく十分かもしれません)、アンパック一般化を使用してfirstlastを別々に取得します真ん中:

first, *_, last = some_list

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

他の多くのソリューションとは異なり、このソリューションでは、シーケンスに少なくとも2つの要素が存在することが保証されます。 1つしかない場合(したがってfirstlastは同じです)、例外(ValueError)が発生します。

6
ShadowRanger

次のようにできます:

some_list[0::len(some_list)-1]
6
Oleh Prypin

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

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

そのため、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']

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

6
crobc1

これはどうですか?

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

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

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

次のようなものを使用できます

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

本当にスライスを使用したい場合。これの利点は、インデックスエラーを与えることができず、長さ1または0のリストでも機能することです。

2

これは「スライス」ではありませんが、明示的なインデックス作成を使用しない一般的なソリューションであり、問​​題のシーケンスが匿名であるシナリオで機能します(したがって、同じ行で「スライス」を作成し、 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チェックまたは二重インデックス付けなどのために、完全なlistを永続的な名前で保存せずに1回だけlen

複数のアイテムのitemgetterは、Tupleではなくlistを返すため、特定の名前に展開するだけでなく、真のlistが必要な場合は、 'listコンストラクターで呼び出しをラップする必要があります。

2
ShadowRanger

より一般的な場合:リストの各端から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]
2
Vlox

別のpython3ソリューションは、「*」文字を使用したTupleアンパックを使用します。

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

これらはすべて興味深いものですが、バージョン番号があり、stringの1つのセグメントのサイズがわからず、最後のセグメントを削除したい場合はどうでしょう。 20.0.1.300のようなもので、最後に300を付けずに20.0.1になりたいです。これまでのところこれがあります:

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

次のようにリスト形式で返されます。

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

ピリオドで区切られた単一の文字列に戻すにはどうすればよいですか

20.0.1
0
Keith