この記事を読むことで、PythonとGASでforループとループの中で単純なIF文を使ってリスト(配列)の中で指定の数がある位置を求めることができるようになります。
このコーナーでは、学習コンテンツpaizaラーニングのレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。
GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。
paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験
paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。
問題:
N 個の整数 a_1, a_2, …, a_N が与えられます。
a_1, a_2, …, a_N のうち、1 がある位置を先頭から順に改行区切りで出力してください。
a_1 を 1 番目とし、a_1, a_2, …, a_N には少なくとも 1 個は 1 が含まれます。
この記事では、下記の入力例2の場合を例にして、標準入力でリストの要素数N=5とリストを取得した後にリストarrayを取得し、その中に1が含まれている位置を出力します。リスト(配列)の先頭は0から始まります。下記の例では、リストの添字0と4が求まるので、それらに1を加えた1と5を出力するようにコードを書いて行きます。
入力例2
5
1 5 5 5 1
出力例2
1
5
ではまず、Pythonで解いてみます。
今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。
■ Pythonでの解き方 ■
下準備として、paiza.ioにこの様に入力します。
(入力例2をそのままioにコピーしただけ。)
手順として、
1:Nを標準入力で取り込む
2:リストarrayを標準入力で取り込む
3:ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する
で、行います。
リストの添字は0から始まる為、「i+1」と1を加えています。
では、ループのトレースを行います。
i=0の時
array[0]=1でリストの中身が1の条件に該当するので、i=0に1を加えた「1」を出力します。
i=1の時
array[1]=5で条件に該当しないのでIF文は飛ばします。
i=2の時
array[2]=5で条件に該当しないのでIF文は飛ばします。
i=3の時
array[3]=5で条件に該当しないのでIF文は飛ばします。
i=4の時
array[4]=1でリストの中身が1の条件に該当するので、i=4に1を加えた「5」を出力します。
ここまでのトレースのコードです。
#Nを標準入力で取り込む
N=int(input())
#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))
#ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する
print('<<<ループに入ります>>>')
for i in range(N):
print('array['+str(i)+']の中身は「'+str(array[i])+'」です。')
if array[i]==1:
print('1見っけ!! i+1=【'+str(i+1)+'】を出力します')
print(i+1)
print('------------------')
print('<<<ループを抜けました。>>>')
このままでは、出力結果である出力例2に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。
#Nを標準入力で取り込む
N=int(input())
#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))
#ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する
#print('<<<ループに入ります>>>')
for i in range(N):
#print('array['+str(i)+']の中身は「'+str(array[i])+'」です。')
if array[i]==1:
#print('1見っけ!! i+1=【'+str(i+1)+'】を出力します')
print(i+1)
#print('------------------')
#print('<<<ループを抜けました。>>>')
スッキリするように、コメントアウトした部分を省いたコードです。
#Nを標準入力で取り込む
N=int(input())
#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))
#ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する
for i in range(N):
if array[i]==1:
print(i+1)
■ GASでの解き方 ■
では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。
スプレッドシートの緑のセルに配列の数の整数5を入力しました。
灰色のセルには配列を入力しました。
黄色いセルには配列の中にある「1」を見つけたらその場所がどこにあるのか出力します。配列の添字は0から始まるため、出力する値は「i+1」です。
※スプレッドシートに表示する場合は、二次元配列としてからの配列に追加をして作成します※
手順はこのようになります。
1:スプレッドシートからアクティブシートにアクセスする
2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する
3:スプレッドシートの灰色のセルから配列arrayを取得する
4:配列arrayが取得出来たことを確認するために出力する
5:配列arrayの中に1を見つけたらその位置「i+1」を格納する配列oneを宣言する
6:ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する
7:ループを抜けてスプレッドシートに出力前の二次元配列oneをログ出力して確認する
8:スプレッドシートの黄色い所に配列arrayの中に含まれている1の位置が格納された二次元配列oneを出力する
手順1: スプレッドシートからアクティブシートにアクセスする
const ss=SpreadsheetApp.getActiveSheet();
ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。
手順2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する
const N=ss.getRange(1,2).getValue();
手順3:スプレッドシートの灰色のセルから配列を取得する
const array=ss.getRange(2,2,1,N).getValues();
手順4:配列が取得出来たことを確認するために出力する
console.log(array);
手順5:配列arrayの中に1を見つけたらその位置「i+1」を格納する配列oneを宣言する
let one=[];
手順6:ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する。
スプレッドシートでは二次元配列として取得されるので、array[0][i]と書いています。
また、配列は添字が0から始まるので「i+1」をしています。
i=0の時
array[0][0]=1でリストの中身が1の条件に該当するので、i=0に1を加えた「1」を出力します。
i=1の時
array[0][1]=5で条件に該当しないのでIF文は飛ばします。
i=2の時
array[0][2]=5で条件に該当しないのでIF文は飛ばします。
i=3の時
array[0][3]=5で条件に該当しないのでIF文は飛ばします。
i=4の時
array[0][4]=1でリストの中身が1の条件に該当するので、i=4に1を加えた「5」を出力します。
ここまでを踏まえて、ループの部分のコードを掲載します。
//ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する
console.log('<<<ループに入ります。>>>');
for(let i=0;i<N;i++){
console.log(`現在の配列one:[[${one}]]`);
console.log(`i:${i}の時、配列では先頭から${i+1}番目でarray[0][${i}]=${array[0][i]}`);
if(array[0][i]==1){
console.log(`1見っけ(=^x^=)!! 配列oneに【${i+1}】を追加`);
one.push([i+1]);
console.log(one);
}
console.log('------------------------------------------------');
}
console.log('<<<ループを抜けました。>>>');
手順7:ループを抜けてスプレッドシートに出力前の二次元配列oneをログ出力して確認する
console.log(one);
手順8:スプレッドシートの黄色い所に配列arrayの中に含まれている1の位置が格納された二次元配列oneを出力する
ss.getRange(4,2,one.length).setValues(one);
実行後のスプレッドシートです。
GASでの全コードはこちらになります。
function loop2no18(){
//スプレッドシートからアクティブシートにアクセスする
const ss=SpreadsheetApp.getActiveSheet();
//スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する
const N=ss.getRange(1,2).getValue();
//スプレッドシートの灰色のセルから配列arrayを取得する
const array=ss.getRange(2,2,1,N).getValues();
//配列arrayが取得出来たことを確認するために出力する
console.log(array);
//配列arrayの中に1を見つけたらその位置「i+1」を格納する配列oneを宣言する
let one=[];
//ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する
console.log('<<<ループに入ります。>>>');
for(let i=0;i<N;i++){
console.log(`現在の配列one:[[${one}]]`);
console.log(`i:${i}の時、配列では先頭から${i+1}番目でarray[0][${i}]=${array[0][i]}`);
if(array[0][i]==1){
console.log(`1見っけ(=^x^=)!! 配列oneに【${i+1}】を追加`);
one.push([i+1]);
console.log(one);
}
console.log('------------------------------------------------');
}
console.log('<<<ループを抜けました。>>>');
//ループを抜けてスプレッドシートに出力前の二次元配列oneをログ出力して確認する
console.log(one);
//スプレッドシートの黄色い所に配列arrayの中に含まれている1の位置が格納された二次元配列oneを出力する
ss.getRange(4,2,one.length).setValues(one);
}
宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。
大井競馬場メガイルミの噴水
■ 参考文献の紹介■
じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。
初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。
GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。
paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験