LoginSignup
2
1

More than 5 years have passed since last update.

「配列の要素のうち、条件に一致する最初の要素の位置」をワンライナーで求めたい(Python3)

Posted at
numbers = [3, 5, 4, 2, 1]
numbers.index{|val| val % 2 == 0} #=> 2

配列の要素を先頭から見ていき、条件に一致する最初の要素の位置がほしいということがよくあります。例として整数が格納された配列のうち、偶数となる最初の要素の位置を求めることを考えましょう。Rubyだと上記のようなワンライナーにより求めることができますが、Pythonではどのように書くべきでしょうか?

numbers = [3, 5, 4, 2, 1]
min((i for i in range(len(numbers)) if numbers[i] % 2 == 0), default=-1) #=> 2

与えられた条件を満たす要素のうち、添え字が最も小さいものを返すイメージですね。なお組み込み関数minは与えられたイテレータが空のとき、例外を投げます。上記の例でいえば配列numbersの中に偶数がない場合、i for i in range(len(numbers)) if numbers[i] % 2 == 0が空になり、例外扱いとなります。ただしキーワード引数defaultを指定すると、イテーレタが空でも例外にはならず、代わりにdefaultに指定した値を返します。要するにnumbersに偶数が存在する場合は最初の偶数の要素の位置、存在しない場合は-1を返すわけです。

ちなみに内包記法を使わないとなると次のようになりますが、Pythonらしいかどうかといわれると首をひねらざるを得ない見た目になってしまいます。そもそも可読性が高いとも思いません。またPythonの無名関数は特有の癖があるため、あまり使いたくないというのが本音だったりします。

numbers = [3, 5, 4, 2, 1]
min(filter(lambda i : numbers[i] % 2 == 0, range(len(numbers))), default=-1) #=> 2

余談: 最初にあげたRubyの例ですが、次のように書くこともできます。

numbers = [3, 5, 4, 2, 1]
numbers.index(&:even?) #=> 2
2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1