概要

やったー!! Python の時間だよ! 今回は最近知り合ったひとが見せてくれた単純な問題を解くぜ。

  • ひと: 大学で Python の宿題が出たんですよー。
  • 緑: マジすか! どんなん!
  • ひと: こんなん!
# こういう表が……
| 1 | 2 | 3 |   |
| 9 | 8 | 7 | 6 |
| 4 | 5 |   |   |

# こんな2次元配列で与えられるから……
[[1, 2, 3], [9, 8, 7, 6], [4, 5]]

# そん中の最大値について、 (上から何行め?, (左から何列め?, その最大値)) の形式で出せ!
(1, (0, 9))

 

縛り条件

はは、賢明なるみろりHP読者の諸君は、こんなもん赤子の手を引きちぎるよりカンタンだとお思いだろう。今回の問題には条件があるのだよ。

  • for 文使用禁止
  • ただし内包表記は可

ハイ、一気に面白そうになってきたーーー!!

 

内包表記を使って解く

# 内包表記、解禁ばーじょん。
def find_max_indices(M):

    # 子リストのそれぞれ、最大値なに?
    max_numbers = [max(_) for _ in M]

    # 最大値、判明〜。
    max_number = max(max_numbers)

    # 行、判明〜。
    i = max_numbers.index(max_number)

    # 列、判明〜。
    j = M[i].index(max_number)

    # こたえは (行, (列, 最大値)) の形式らしいよ。
    return (i, (j, max_number))


print(find_max_indices([[1, 2, 3], [9, 8, 7, 6], [4, 5]]) == (1, (0, 9)))  # true!
print(find_max_indices([[1, 2, 3], [0, 9, 8, 7, 6], [4, 5]]) == (1, (1, 9)))  # true!

出来たぜ! まあ、大学の宿題であるという点を鑑みれば、これは内包表記を使う練習問題なのだと考えるのが妥当だろう。これは素直な回答といえるね。

 

内包表記を封印して解く

だが Pythonista の末席を汚す者としては、ガチ for 禁止で解かなければなるまい。ようは max_numbers = [max(_) for _ in M] のとこを内包表記なしで実現すればいいわけだ。

# 内包表記、封印ばーじょん。
def find_max_indices(M):

    # M ってなんこリスト入ってる?
    m_len = len(M)

    # max_numbers = [max(_) for _ in M] これを再現するー。
    max_numbers = []
    a = 0
    def foo(a):
        if a == m_len:
            return
        max_numbers.append(max(M[a]))
        a += 1
        foo(a)
    foo(a)

    # あとは解禁ばーじょんとおなじ

    # 最大値、判明〜。
    max_number = max(max_numbers)

    # 行、判明〜。
    i = max_numbers.index(max_number)

    # 列、判明〜。
    j = M[i].index(max_number)

    # こたえは (行, (列, 最大値)) の形式らしいよ。
    return (i, (j, max_number))


print(find_max_indices([[1, 2, 3], [9, 8, 7, 6], [4, 5]]) == (1, (0, 9)))  # true!
print(find_max_indices([[1, 2, 3], [0, 9, 8, 7, 6], [4, 5]]) == (1, (1, 9)))  # true!

そう、再起関数!

 

おしまい

完クリしたぜ。ようは「内包表記超ステキ」ってことだな。