Pythonリストのn番目の要素、または利用できない場合のデフォルトを取得する方法


144

私はPythonのdictionary.get(key, default)forリストに相当するものを探しています。リストのn番目の要素を取得するための1つのライナーイディオムまたは利用できない場合のデフォルト値はありますか?

たとえば、取得したいリストmyList myList[0]またはmyList空のリストの場合は5を指定します。

ありがとう。

回答:


124
l[index] if index < len(l) else default

負のインデックスをサポートするために使用できます:

l[index] if -len(l) <= index < len(l) else default

3
ただし、リストに名前がない場合、たとえばリスト内包表記では機能しません。
Xiong Chiamiov 2011

9
マイナス指数の場合を忘れたようです。例えば。index == -1000000戻る必要がありdefaultます。
nodakai 2012年

3
@nodakai、良い点。私は時々これに噛まれました。ネガティブにx[index] if 0 <= index < len(x) else defaultなることができればもっと良いでしょうindex
Ben Hoyt 2013

3
@nodakai wow-これは、テストを正しくコーディングして失敗しないようにするよりも、try / exceptを使用した方がよい理由の良い例です。私はまだtry / exceptに依存するのは好きではありません。発生することがわかっている場合のためですが、これはそれを検討する意欲を高めます。
ToolmakerSteve

6
@ToolmakerSteve:の式valid_index()が正しくありません。負のインデックス Pythonでは合法です-あるべきです-len(l) <= index < len(l)
Tim Pietzcker 2014年

57
try:
   a = b[n]
except IndexError:
   a = default

編集:TypeErrorのチェックを削除しました-おそらく呼び出し元にこれを処理させる方が良いでしょう。


3
私はこれが好き。引数としてイテラブルを使用して呼び出すことができるように、関数をラップするだけです。読みやすい。
Noufal Ibrahim

35
(a[n:]+[default])[0]

a大きくなるにつれてこれはおそらくより良いです

(a[n:n+1]+[default])[0]

これa[n:]は機能します。n => len(a)

これがどのように機能するかの例です range(5)

>>> range(5)[3:4]
[3]
>>> range(5)[4:5]
[4]
>>> range(5)[5:6]
[]
>>> range(5)[6:7]
[]

そして完全な表現

>>> (range(5)[3:4]+[999])[0]
3
>>> (range(5)[4:5]+[999])[0]
4
>>> (range(5)[5:6]+[999])[0]
999
>>> (range(5)[6:7]+[999])[0]
999

5
これを説明するコメントなしで実際のコードでこれを書きますか?
Peter Hansen

1
@Peter Hansen、私がゴルフをしていた場合のみ;)ただし、Pythonのすべてのバージョンで動作します。承認済みの回答は
2.5+で

3
ただし、アイテムを選択するために、3つの一時リストを作成し、2つのインデックスにアクセスします。
Joachim Jablon 14

これを「実際の」コードで実行することはありませんが、Python REPLで簡単に使用できる簡潔な1行なので、賛成票を得ることができます。
Cookyt

next(iter(lst[i:i+1]), default)-謎めいた醜いワンライナーコンテストのもう1つのエントリ。
jfs 2018年

28

ちょうどそれを発見しました:

next(iter(myList), 5)

iter(l) イテレータを返します myListnext()反復子の最初の要素を消費し、上昇しStopIteration、ここでは二番目の引数の場合で、デフォルト値、と呼ばれている場合を除き、エラーを5

これは、例のように最初の要素が必要な場合にのみ機能しますが、質問のテキストでは機能しないため、...

さらに、メモリに一時的なリストを作成する必要はなく、名前がなくても、あらゆる種類のイテラブルで機能します(gruszczyの回答に関するXiong Chiamiovのコメントを参照)


3
他の回答と組み合わせると、これ next(iter(myList[n:n+1]), 5)nth要素に対して機能します。
Alfe、2018年

リスト以外では機能しません。この時点で、try:except-IndexErrorは、より良いアイデアのように見えます。また、メモリ内にリストを作成します。
Joachim Jablon

tryバリアントは(OPによりを求め頼む)ワンライナーではありません。myListはOPで指定されたリストであるため、リストに対してのみ機能します(正確には、インデックス可能なものです)。ここでは1つの(または何もない)要素のリストを作成しているので、メモリ内にコピーを作成してもコストはかかりません。確かに、少しオーバーヘッドがありますが、ループで何百万回も実行しない限り、言及する価値はありません。ところで、IndexError例外の作成とキャッチはおそらくもっとコストがかかると思います。
Alfe、2018年

可読性は重要です:) IndexErrorを発生させるのにかなりのコストがかかる場合は、Pythonですべてを行う必要があります。
Joachim Jablon

20
(L[n:n+1] or [somedefault])[0]

1
+1。これにより、私は何を[] or ...したかを学びに行きました。しかし、私は個人的には、(初心者にとって)簡単に読めるので、受け入れられたソリューションを使用します。確かに、それをコメント付きの 'def'でラップすると、ほとんど問題にならないでしょう。
ToolmakerSteve

どのような場合L[n] == Falseか、L[n] == NoneまたはL[n] == []以上のグローバル何falseと評価こと?
Joachim Jablon

@JoachimJablon:まだ動作します。スライスはリストを返し、[False]真です。
Ignacio Vazquez-Abrams

ああ、確かにリストがチェックされていて値ではないことに気づかなかった。
Joachim Jablon

なぜこれをタプルでラップするのですか?私はmyval = l[n:n+1] or [somedefault]うまくいくと思いますか?
ロタレティ2018年

8

... dict.get(key, default)forリストのPythonで同等のものを探しています

一般的なイテラブルに対してこれを行うitertoolsレシピがあります。便宜上、> pip install more_itertoolsこのようなレシピを実装する次のサードパーティライブラリをインポートできます。

コード

import more_itertools as mit


mit.nth([1, 2, 3], 0)
# 1    

mit.nth([], 0, 5)
# 5    

細部

これがnthレシピの実装です:

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(itertools.islice(iterable, n, None), default)

のようにdict.get()、このツールは欠落しているインデックスのデフォルトを返します。これは一般的なイテラブルに適用されます:

mit.nth((0, 1, 2), 1)                                      # tuple
# 1

mit.nth(range(3), 1)                                       # range generator (py3)
# 1

mit.nth(iter([0, 1, 2]), 1)                                # list iterator 
# 1  

2

安価な解決策は、実際に列挙して口述を作成し、.get()いつものように使用することです、

 dict(enumerate(l)).get(7, my_default)

1

@Joachimと上記のものを組み合わせて、

next(iter(my_list[index:]), default)

例:

next(iter(range(10)[8:]), 11)
8
>>> next(iter(range(10)[12:]), 11)
11

または、おそらくより明確ですが、 len

my_list[index] if my_list[index:] else default

1

Python 3.4を使用してと同様contextlib.suppress(exceptions)getitem()メソッドを構築しgetattr()ます。

import contextlib

def getitem(iterable, index, default=None):
    """Return iterable[index] or default if IndexError is raised."""
    with contextlib.suppress(IndexError):
        return iterable[index]
    return default
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.