[Pythonクイズ]あなたのPython力が試される! all関数の戻り値がどうなるか、説明できますか?:Pythonステップアップクイズ
Pythonにall関数ってありますよね。使ったことあります? もちろん? そんなあなたに問いたい。このリストを渡したときに、戻り値がどうなるかを。分かりますよね?
【問題】
以下に示す8つのリストの中で、all関数に渡したときにTrueが返されるものを選べ(複数選択可)。
lst1 = []
lst2 = [0, 1, 2]
lst3 = [1, 2, 3]
lst4 = [[]]
lst5 = [[0, 1, 2]]
lst6 = [[], []]
lst7 = [[[]]]
lst8 = [[[1, 2, 3]]]
どうもHPかわさきです。
今回はちょっとマニアックな内容といえるかもしれません。all関数の挙動やリストの要素がどんなときに真と評価されるか(偽と評価されるか)について知っていればカンタンに解けるでしょうが、「そんなところまで知っている必要ある?」と思う方もいらっしゃるかもしれませんねぇ。ちょっとした頭の体操だと思って、考えてみてください。
【答え】
問題に挙げた8つのリストをall関数に与えたときの戻り値がどうなるかを確かめるコードを以下に示します。
lst1 = []
lst2 = [0, 1, 2]
lst3 = [1, 2, 3]
lst4 = [[]]
lst5 = [[0, 1, 2]]
lst6 = [[], []]
lst7 = [[[]]]
lst8 = [[[1, 2, 3]]]
lsts = [lst1, lst2, lst3, lst4, lst5, lst6, lst7, lst8]
for n, lst in enumerate(lsts, 1):
res = all(lst)
print(f'lst{n}: all({lst}) -> {all(lst)}')
このコードを実行した結果を以下に示します。
というわけで、Trueを返すかどうかは以下の通りです。
- lst1 = []:○
- lst2 = [0, 1, 2]:×
- lst3 = [1, 2, 3]:○
- lst4 = [[]]:×
- lst5 = [[0, 1, 2]]:○
- lst6 = [[], []]:×
- lst7 = [[[]]]:○
- lst8 = [[[1, 2, 3]]]:○
Trueを返すのはlst1、lst3、lst5、lst7、lst8の5つでした。
【解説】
all関数は引数として与えたリスト(反復可能オブジェクト)の要素が全て真ならTrueを、真でないものが1つでもあればFalseを返す関数です。Pythonのドキュメントにもありますが、この振る舞いは次のように書けます。
def myall(iterable):
for element in iterable:
if not element:
return False
return True
Pythonでは0や空文字列、空のリストなどは偽と評価されることは知っているでしょう。問題文に挙げた8つのリストの要素について考えてみます。
- lst1:[]
- lst2:[0, 1, 2]
- lst3:[1, 2, 3]
- lst4:[[]]
- lst5:[[0, 1, 2]]
- lst6:[[], []]
- lst7:[[[]]]
- lst8:[[[1, 2, 3]]]
lst1はそもそも要素がありません。その場合はどうなるんだ? というのは後で考えます。他のリストの要素について順番に見てみましょう。
- lst2:0を含んでいるので全てが真ではない(False)
- lst3:全要素が整数値で0を含んでいないので、全て真である(True)
- lst4:空のリストが1つだけなので、全ての要素が真ではない(False)
- lst5:空ではないリスト(1個)を要素としているので、全ての要素が真である(True)。この場合、リストが空でないことからTrueと評価されるのであり、リストに0が含まれているかどうかは関係ないことに注意
- lst6:空のリスト2つが要素なので、全ての要素が真ではない(False)
- lst7:このリストの要素は「空のリストを含むリスト」である(「内側のリスト」とする)。内側のリストに着目すると、その要素は空リストだが、内側のリスト自体は空ではないので、真と評価される(True)
- lst8:内側のリストは空ではないリストを要素とする。もちろん、真と評価される(True)
こんな感じでしょうか(lst7はちょっと分かりにくいかもしれません)。
さて、最後に残ったlst1ですが、上掲のmyall関数ではiterableパラメーターに受け取った値を反復して、反復された値が1つでも偽と評価されたらFalseを返すようになっています。しかし、反復可能オブジェクトが空だった場合にはfor文は実行されずに、Trueが返されることに注目してください。lst1はこちらの実行パスを通るのでTrueが返されるというわけです。
「空のリストを渡すとTrueが返される」というのはドキュメントに書いてある通りなので「そんなの、当たり前だよ!」となる人も多いでしょう。でも、「空のリストを要素とするリストを要素とするリスト」を渡すとTrueになるってのはなかなか分かりにくいところかもしれませんね。実際にそうしたリストをall関数に渡すことがあるかどうか、それは筆者には分かりませんけれど……。
all関数(と対になるany関数)については「Python入門」の「リストと繰り返し処理」や「解決!Python」の「all/any関数を使って、リストなどの要素が全て真か/偽か、真な要素があるか/偽な要素があるかを調べるには」でも取り上げています。興味のある方はぜひそちらにも目を通してみてくださいね。
Copyright© Digital Advantage Corp. All Rights Reserved.