1. ホーム
  2. python

[解決済み] 最初の項目または None を返す Python のイディオム

2022-03-15 05:04:36

質問

もっと簡単な方法があると思うのですが、私には思いつきません。

リストを返すメソッドをたくさん呼び出しています。 そのリストは空かもしれません。 リストが空でない場合は、最初の項目を返し、そうでない場合は None を返したい。 このコードは動作する。

my_list = get_list()
if len(my_list) > 0: return my_list[0]
return None

これを行うための簡単な1行イディオムがあるはずだと思うのですが、どうしても思いつきません。 あるのでしょうか?

編集してください。

ここで一行表現を求めているのは、信じられないほど簡潔なコードが好きだからではなく、このようなコードをたくさん書かなければならないからです。

x = get_first_list()
if x:
    # do something with x[0]
    # inevitably forget the [0] part, and have a bug to fix
y = get_second_list()
if y:
    # do something with y[0]
    # inevitably forget the [0] part AGAIN, and have another bug to fix

私がやりたいことは、確かに関数で実現できる(そしておそらくそうなる)。

def first_item(list_or_none):
    if list_or_none: return list_or_none[0]

x = first_item(get_first_list())
if x:
    # do something with x
y = first_item(get_second_list())
if y:
    # do something with y

Pythonの簡単な式でできることによく驚かされるので、簡単な式でできることがあるなら、関数を書くのは馬鹿らしいと思ったので、質問を投稿しました。 しかし、これらの回答を見ていると、どうやら関数は というシンプルな答えです。

解決方法は?

Python 2.6+

next(iter(your_list), None)

もし your_listNone :

next(iter(your_list or []), None)

Python 2.4

def get_first(iterable, default=None):
    if iterable:
        for item in iterable:
            return item
    return default

x = get_first(get_first_list())
if x:
    ...
y = get_first(get_second_list())
if y:
    ...

もう一つの方法は、上記の関数をインライン化することです。

for x in get_first_list() or []:
    # process x
    break # process at most one item
for y in get_second_list() or []:
    # process y
    break

を回避するために break と書けばいい。

for x in yield_first(get_first_list()):
    x # process x
for y in yield_first(get_second_list()):
    y # process y

どこで

def yield_first(iterable):
    for item in iterable or []:
        yield item
        return