eljefeblog 

Any sufficiently advanced technology is indistinguishable from magic

python_problems

独学でPython『リスト操作』の基本を学ぶ【プログラミング基礎練習問題2】

独学でPython『リスト操作』の基本を学ぶ【プログラミング基礎練習問題2】




(Pythonの基本を初めからしっかり学びたい方はこちら↓↓)



プログラミングの基本文法を学んだ方からよくこのような質問を頂きます。

悩むペン銀

Pythonの基本構文を学んで、プログラミングに対する基礎知識もある程度勉強したんだけど、次に何をすればいいのか分からない。次に何をすればより成長できるか教えて欲しい



こう言った『次に何すればいいか分からない』と言う疑問に対し



僕からの回答を言うと、



『沢山問題を解きましょう』

です。




これこそプログラミング力を飛躍的に向上させる一番の近道です。



このシリーズを最後まで学習することで、これまで学んできた基礎知識を定着させ、
最終的に様々な問題を、Pythonを駆使して解決できるようになるはずです。



本シリーズを習得した後、
得ることができる主な知識・内容は以下3点です。


本記事の内容

  • 基礎問題を解き、リスト操作の基礎知識を獲得する
  • リスト操作を行う上で役立つ組み込み関数に関する知識
  • 配列操作の応用方法について


  • この記事を書いている僕は国立大学にてCSの学位を保有しており
    エンジニアとしての仕事では現実問題を解き続けています。



    実際に問題を解いていくと今まで知らなかった便利な組み込み関数や
    新しい思考プロセスを学ぶことができます。



    それではやっていきましょう。







    (注) 問題のレベルについて



    以下に示す問題のレベルは五段階に分割しています。
    あくまでも目安なので、自分が解いてみたい・解ける問題から手をつけてみてください。

    解けない問題は無理して解いて理解しようとせず、もう少し学びを深めてから取り組みましょう。意外と時間を置いて取り組むと、あっさり解けたりします。


    プログラミングの勉強は継続が重要です。なので楽しさを優先しましょう!


  • very easy
  • easy
  • normal
  • difficult
  • very difficult





  • 【問題1】リスト操作 レベル: difficult


    地雷の場所を特定せよ

    【問題】

    引数として"=""*"が要素として格納されたリストが与えられる。"*"は地雷の場所を示していて、"="は地雷が無い地点だ。この時、地雷を囲う場所(縦・横・斜め)に1を、そのほかの地雷が無い場所には0を加算して表示して欲しい。戻り値はリスト型であり、関数名はcreateBombBoardとしよう。



    具体例


    createBombBoard関数に引数を渡した場合
    以下のような結果となります。

  • createBombBoard([ ["=", "=", "=", "=", "="], ["=", "=", "=", "=", "="], ["=", "=", "*", "=", "="], ["=", "=", "=", "=", "="], ["=", "=", "=", "=", "="] ]) → [[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, "*", 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]]
  • createBombBoard([ ["*", "=", "=", "=", "*"], ["=", "=", "=", "=", "="], ["=", "=", "*", "=", "="], ["=", "=", "=", "=", "="], ["=", "=", "=", "=", "*"] ]) ➞ [ ["*", 1, 0, 1, "*"], [1, 2, 1, 2, 1], [0, 1, "*", 1, 0], [0, 1, 1, 2, 1], [0, 0, 0, 1, "*"] ]



  • 注意事項



    以下、実装における注意事項です。

  • 引数として文字列の要素を格納したリストを1つ受け取る
  • 戻り値として地雷の場所を”*”の文字列で、そのほかの場所をint型の数値で返す



  • テスト


    以下のテストコードをエラー無く通過できれば正解です。
    作成した関数を以下のように自分の環境に書き込んで完成させ
    Runボタンを押して確認してみましょう。

    # This will get executed each time the exercise gets initialized def createBombBoard(arg): ここにコードを入力してください return your_answer data = [ ["*", "=", "=", "=", "*"], ["=", "=", "=", "=", "="], ["*", "=", "=", "=", "="], ["=", "=", "=", "*", "="], ["=", "=", "*", "=", "="] ] assert createBombBoard(data) == [[0, 1, 0, 1, 0], [2, 2, 0, 1, 1], [0, 1, 1, 1, 1], [1, 2, 2, 1, 1], [0, 1, 1, 2, 1]] data = [ ["=", "=", "=", "*", "="], ["=", "*", "=", "=", "="], ["=", "=", "=", "=", "="], ["=", "=", "=", "*", "="], ["*", "*", "=", "=", "="] ] assert createBombBoard(data) == [[1, 1, 2, 0, 1], [1, 0, 2, 1, 1], [1, 1, 2, 1, 1], [2, 2, 2, 0, 1], [1, 1, 2, 1, 1]] print('Pass!!')
    Use the assignment operator (<-) to create the variable a.




    解答例

    
    def createBombBoard(arg):
        import numpy as np
        result = np.zeros(np.array(arg).shape, dtype=np.int8)
        for idx_row, row in enumerate(arg):
            for idx_col, col in enumerate(row):
                if col == '*':
                    data = [[idx_row-1, idx_col-1], [idx_row-1, idx_col], [idx_row-1, idx_col+1], [idx_row,idx_col-1], [idx_row, idx_col+1], [idx_row+1, idx_col-1], [idx_row+1, idx_col], [idx_row+1, idx_col+1]]
                    for l in data:
                        try:
                            if l[0] < 0 or l[1] < 0:
                                continue
                            result[l[0], l[1]]+=1
                        except IndexError:
                            continue
                elif col == '=':
                    continue
        return result.tolist()
    
    


    解説付き解答例

    
    
    def createBombBoard(arg):
    
        import numpy as np # python数値計算ライブラリnumpyのimport
    
        # np.zeros関数は0で初期化されたndarrayを生成する。
        # 生成するサイズは引数で与えられたlistと同じ次元のものを取得する為
        # np.array(arg).shapeでサイズを取得して引数に与えている
        result = np.zeros(np.array(arg).shape, dtype=np.int8) 
    
        # 引数で与えられたリストの行毎の要素にアクセス
        for idx_row, row in enumerate(arg):
            # リストの列毎の要素にアクセス
            for idx_col, col in enumerate(row):
                # リストにおける爆弾の場所を特定し、その全方位の場所も特定する
                if col == '*':
                    data = [[idx_row-1, idx_col-1], [idx_row-1, idx_col], [idx_row-1, idx_col+1], [idx_row,idx_col-1], [idx_row, idx_col+1], [idx_row+1, idx_col-1], [idx_row+1, idx_col], [idx_row+1, idx_col+1]]
                    for l in data:
                        try:
                            if l[0] < 0 or l[1] < 0:
                                continue
                            # 地雷の全方位のマスをインクリメントする
                            result[l[0], l[1]]+=1
                        except IndexError:
                            continue
                # 爆弾以外の場所は無視する
                elif col == '=':
                    continue
        # np.arrayで操作してきた為、リスト型に変換し、値を返す
        return result.tolist()
    


    更に深く学ぶ+α

    配列とリストは性質が違う


    Pythonでは、(一般的に他の言語でも)配列とリストの性質は異なります。 配列とリストの違いは何か。それはデータ構造にあります。 例えば数値データを効率的に処理するためのモジュールとして、Pythonには外部ライブラリnumpyのndarrayや組み込みモジュールのarrayが用意されています。 これらのデータ構造では 隣り合う要素がメモリ上で連動している 同じ型の変数しか格納できない等の特徴があります。 一方でリストではメモリ上で数値が連続して格納されることは保証されていませんが、様々な型のオブジェクトを保持することができます。

    enumerate関数について


    enumerate関数は要素のインデックスと要素を同時に取り出したい時に役に立つ関数です。たとえば以下のようにして活用できます。
    
    for idx, element enumerate(["太郎", "次郎", "三郎"]):
        print(idx, element)
    
    0, "太郎"
    1, "次郎"
    2, "三郎"
    
    
    このように、enumerateを使うことで引数で与えられたリストの要素が 1つずつ取り出されると同時にそのインデックスが0から順に取得できます。











    【問題2】リスト操作 レベル: easy


    リスト内要素の順番を調査せよ


    【問題】

    引数として整数型の数字を格納した2つのリストを受け取る。これらをマージし、1つのリストにして要素を昇順(0,1,2,3,4...)に並び替えよう。この時、値が飛ぶことなく順番通りの要素が格納されている場合はTrueを。そうでない場合はFalseを返すcheckOder関数を実装せよ。




    具体例


    実装したcheckOder関数に引数を与えた時、
    結果は以下のようになります。

    
    checkOder([2,3,1,4],[5,8,6,7])→True
    checkOder([3,2,4,5],[9,6,10,1])→False
    checkOder([4,9,2,1,8],[13,12,11,10,3])→False
    
    



    注意事項


    以下の要件にしたがって関数を設計してください

  • 引数のリスト内の要素はInt型オンリー
  • 引数のリストサイズが違っても大丈夫
  • 引数のリスト内の要素はユニーク(ダブりがない)


  • テスト


    以下のテストコードをエラー無く通過できれば正解です。
    あなたの回答を書き込んで関数を完成させ、Runボタンを押して確認してみましょう。

    # This will get executed each time the exercise gets initialized def merge_dictionary(dict1,dict2): #ここにコードを入力してください return your_answer arg1 = [2,3,5] arg2 = [0,1,4] assert checkOder(arg1, arg2) == True arg1 = [5,3,2,8] arg2 = [0,1,4,6,7] assert checkOder(arg1, arg2) == True arg1 = [0,9,2,1,4,5] arg2 = [6,3] assert checkOder(arg1, arg2) == False print('Pass!!')
    Use the assignment operator (<-) to create the variable a.



    解答例


    少なくとも10分間は自分の頭で考えて問題を解きましょう。
    10分考えても解法が浮かばない場合は解答例を見て、問題の解き方を学んでください。

    
     def checkOder(arg1,arg2):
         tmp_list = arg1
         for i in arg2:
             tmp_list.append(i)
         sorted_list=sorted(result)
         result = []
         for i, e in zip(sorted_list, range(min(sorted_list),max(sorted_list)+1)):
             if i == e:
                 result.append(0)
             else:
                 result.append(1)
         if sum(result) == 0:
             return True
         else:
             return False
       



    解説付き解答例

    
    def checkOder(arg1,arg2):
         tmp_list = arg1 
         for i in arg2: 
             tmp_list.append(i) # arg1とarg2の要素を1つのリストに統合する
         sorted_list=sorted(result) # 統合してできたリストの要素を照準に並び替える
         result = []
         for i, e in zip(sorted_list, range(min(sorted_list),max(sorted_list)+1)):  # 並び替えたリストが要素に欠損なく要素を格納しているか確認する
             if i == e:
                 result.append(0) # 欠損がなければ0
             else:
                 result.append(1) # 欠損があれば1
         if sum(result) == 0:
             return True
         else:
             return False
          



    更に深く学ぶ+α

    sorted関数

    zip関数














    人気記事【初学者必見】効率的なプログラミング勉強方法を紹介します







    このエントリーをはてなブックマークに追加
    data-ad-format="rectangle" data-ad-format="rectangle"

    返信する

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

    某国立大学大学院(理系)に所属しています。 最近の趣味は人工知能関連の論文を読む事で 研究ではComputer Vision周りを中心に活動しており、 サイドワークとしてデータ分析の業務に関わっています。 本ブログはこれまで筆者が学んできた様々な知識の中から 有益だと思えた情報のみをまとめたものです。 内容は個人の見解であり、所属する機関と関係するものではありません。 Research: is related to Computer Vision Hobby: is to study Artificial Intelligence / Machine Learning.