検索
連載

[Pythonクイズ]「if len(yourlist) > 0:」を、もっとシンプルに書ける?Pythonステップアップクイズ

len関数でリストの要素数を調べて、その数が0より大きいかどうかを比較したりしていませんか? チッチッ! リスト(コレクション)の性質を理解して、もっとPythonicなコードを書くようにしましょう!

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Pythonステップアップクイズ」のインデックス

連載目次

このif文には無駄な記述がある。どうすればよりシンプルになるだろう
このif文には無駄な記述がある。どうすればよりシンプルになるだろう

【問題】

 以下はリストを与えると、それが空でなければ「not empty」と、空なら「empty」と表示する関数fooの定義とその呼び出し例である。関数fooのif文は問題なく動作するが、無駄な記述がある。どのように修正できるだろうか。

def foo(yourlist):
    if len(yourlist) > 0:
        print('not empty')
    else:
        print('empty')


mylist = []
foo(mylist)  # empty

このif文には無駄な記述がある。どうすればよりシンプルになるだろう


かわさき

 どうもHPかわさきです。

 最近、Pythonクイズをたくさんの方に見ていただけているようなんですよ。でも、理由が分からないんですよね。そして、見てくれる人が増えているにもかかわらず、Xのフォロワーさんの数は全く増えていないんですよ! 何とかなりません? や、まー、増えなくてもいいんですけどね。目立ちたくないから……(しょぼん)。


【答え】

 正解のコード例を以下に示します。

def foo(yourlist):
    if yourlist:
        print('not empty')
    else:
        print('empty')


mylist = []
foo(mylist)  # empty

len関数でリストの要素数を調べる必要はない

 問題文のコードではlen関数でyourlistに与えられるリストの要素数を取得して、それが0より大きいかどうかをif文で判定していました。実際には、リストが空でなければ真(True)と、空であれば偽(False)として扱われるので、上のコードのように記述できます。

len関数でリストの要素数を調べる必要はない
len関数でリストの要素数を調べる必要はない

【解説】

 問題文にあるfoo関数は、yourlistに受け取ったリスト(あるいは何らかのコレクション)の要素数をlen関数で調べています。そして、それが0より大きければ(リストに要素が1個でも含まれていれば)「not empty」と表示して、そうでなければ(リストに空であれば)「empty」と表示します。

 つまり、if文では「要素数を調べて、それが0より大きいかどうか」ではなく「リストが空でないかどうか」を判定しているといってよいでしょう。もちろん、問題文のコードでも問題なく動作します。

 つまり、問題文にあるコードのifでは以下のような処理をしていました。

if コレクションの要素数 > 0:
    print('not empty')
else# コレクションの要素数が0(マイナスはあり得ない)
    print('empty')

コレクションの要素数が0より大きいかどうかで処理を分岐する

 しかし、これは次のように置き換えられるということです。

if コレクションが空でない:
    print('not empty')
else# コレクションが空
    print('empty')

コレクションの要素数が0より大きいかどうかで処理を分岐する

 では、どうすれば、要素が空でないかどうかを調べられるのでしょう(わざとらしいですねぇ)。

 Pythonではリストやタプル、辞書、集合などのコレクションはそこに要素が1つもない場合、真偽値の判定という場面では偽(False)として扱われます。逆に1つ以上の要素があれば、真(True)として扱われます。おっと忘れていました。文字列も文字を0個以上の文字を含むコレクションなことは思い出しておきましょう。つまり、真偽値の判断において、空文字列は偽(False)として、そうでない文字列は真(True)として扱われます。詳細についてはPythonドキュメント「真理値判定」などを参考にしてください。


かわさき

 この他に偽として扱われるのは、None、False、数値のゼロ(整数値の0、浮動小数点数値の0.0など)、range(0)などです。

 注意したいのは、[0]は0(偽として評価される値)を含んでいますが、空のリストではないので真と評価される点です。0は偽ですし、[]も偽ですが、[0]は真です。慣れないうちは「何で?」となるかもしれませんね。


 以下のコードでは、1個の要素を持つリストをif文の条件に記述しています。

mylist = [0]

if mylist:  # 空のリストじゃないので真
    print('not empty')
else:
    print('empty')

「not empty」と表示される

 mylistは空ではないので、この場合は真と評価され、上のコードでは「not empty」と表示されます。

実行結果
実行結果

 ここではリストを例に取りましたが、他のコレクションでも同様です(気になる方はご自分で試してみてくださいね)。

 というわけで、問題文にあるif文は次のように書き換えられます。

def foo(yourlist):
    if yourlist:
        print('not empty')
    else:
        print('empty')


mylist = []
foo(mylist)  # empty

リストが空でないかどうかで処理を分岐する

 逆に「リストが空の場合」に何かをしたければ、次のようにnot演算子で真偽値を反転させればよいことも覚えておきましょう。

mylist = []

if not mylist# リストが空なら真になる
    print('empty')

コレクションが空のときに何かするならnot演算子を使う

 なお、「要素数が5個よりも多ければ」のような条件のときには、このような単純な置き換えができないことには注意してください。このような置き換えが可能なのは、「コレクションの要素数が0より大きいかどうか = コレクションが空ではないかどうか = コレクションが真かどうか」をチェックしている場合です。


かわさき

 前回の『「list()」vs「[]」。空のリストを作る2つの方法に振る舞いの差はあるのかい?』はバイトコードが出てきたり、実行時間を計測してみたりとちょっと難しく感じたかもしれません。それと比べると、今回は「カンタンだよ!」って人が多いでしょうね。が、この振り幅の広さが大事だと思います(いいネタを思い付かなかったからというわけではないですよ?)。

 そういうわけで、「Python入門」では「if文による条件分岐」なんかがオススメです。


「Pythonステップアップクイズ」のインデックス

Pythonステップアップクイズ

Copyright© Digital Advantage Corp. All Rights Reserved.

[an error occurred while processing this directive]