この記事を読むことでループ文字列の分割、Pythonの標準入力、GASの二次元配列の扱いの概要が掴めます。
このコーナーでは、プログラミング学習コンテンツpaizaラーニング のレベルアップ問題集 を、PythonとGAS(Google Apps Script)の両方で同じ問題を解いたコードを公開している学習ログです。 Python・GASのどちらの言語のコードも可能な限り詳細に解説致します。 GASはスプレッドシートのエディタを使ってコードを書いております。
Pythonではpaizaに入会しなくても問題集を解きたい方向けにpaiza.io を用いております。paiza.ioの使い方はこちら から。 (入会するか否かは問題集を解いて見てからの読者様のご判断にお任せ致します。 どちらの選択をされても記事を読めるようになっておりますので、ご安心なさって下さい。)
数字の受け取り 2 (paizaランク D 相当)
この問題では、最初の行にN個の数字が与えられます。 その下の2行目には具体的な数値が与えられます。
今回は入力例3 を用います。
入力例3 8 8 1 3 8 1 3 8 1
出力例3 8 1 3 8 1 3 8 1
この入力例3 の場合は、1行目に数値の個数8個と、2行目に具体的な8個の数値が与えられます。
ではまず、Pythonで解いて行きます。
■ Pythonでの解き方 ■
paiza.ioに入力例3をそのままコピペします。
コードの手順として、
1. 1行目の数値の個数8を標準入力で変数Nに数値として取得 2. 2行目の8つの数をリスト(配列)として標準入力で取得 3. forループでリストの長さN個分を出力する ・基本的なループ ・リスト出力に便利なループ ・内包表記によるループ
大まかにこの様な流れになります。
手順1: 1行目の数値の個数8を標準入力でNに数値として取得
N=int(input())
この様なコードで標準入力を数値として読み込み、Nを出力して確認します。
#数値の個数を標準入力でNに取得
N=int(input())
#取得出来たことを確認する
print(N)
Nの出力結果です。
無事、数値として標準入力で変数Nに取得出来ました。
手順2: 2行目の8つの数をリスト(配列)として標準入力で取得
2行目の数値8つの区切り文字は半角スペースで、リストarrayに標準入力を用いて取得します。 複数のメソッドなどが登場しているので、この例に沿って役割をまとめます。
input … 標準入力で文字や数値を取得する rstrip… 文字列の末尾の文字を除去 split … 半角スペースなどの指定の区切り文字で分割して取得する int … 上記で取得する対象が数値である map … まとめて適用 list … リスト(配列)変換
こちらのコードでリストarrayに取得します。
array=list(map(int,input().rstrip().split(‘ ‘)))
取得した後、arrayを出力して確認します。
N=int(input())
#print(N) ← コメントアウト
#リスト形式でarrayに8つの数値を標準入力で取得する
array=list(map(int,input().rstrip().split(' ')))
#リストarrayを出力して確認
print(array)
この様に、標準入力を幾つかのメソッドと一緒に使って、arrayがリスト形式になりました。
長さ8のリストarray=[8 , 1 , 3 , 8 , 1 , 3 , 8 , 1]と取り込まれ、その添字ごとの要素は、
array[0]=8, array[1]=1, array[2]=3, array[3]=8, array[4]=1, array[5]=3, array[6]=8, array[7]=1
です。 ループに入る前に一旦コードを整えます。 コメントアウトをした分を削ります。
N=int(input())
array=list(map(int,input().rstrip().split(' ')))
手順3: forループでリストの長さN個分を出力する
今変数Nには、N=8と代入されています。 このNの値をループを用いて出力例3に合わせて縦に出力します。
リストarrayの添字は0から始まるので、i=0〜7までの数字を出すのにそのままrange(N)が使えます。
rangeでは、0からの括弧内の数値未満分カウンタ変数のiがループ内で変わります。
for i in range(N):
array[i]をループで回してiに0から7までの添字が入り、array[0]からarray[7]を出力します。
Pythonでの基本的なループのコードと出力結果はこちらになります。
N=int(input())
array=list(map(int,input().rstrip().split(' ')))
#基本的なループ
for i in range(N):
print(array[i])
次項からは、リストに適したループの便利な記述を掲載します。
リスト出力に適した中でも直感的に分かりやすい書き方は、
for リストの要素の変数名 in リスト名:
となりますので、数値を取り出すと分かりやすい様にリストの要素の数値に該当する変数としてnumを用います。
for num in array:
numを用いることによって、出力するのは数値だというのがコードを書く方も読む方も分かりやすいと思います。 基本的には何でも良いのですが、伝わりやすさから変数名をnumに致しました。
下記のコードで少しシンプルになった上に同様な出力結果が得られます。
N=int(input())
array=list(map(int,input().rstrip().split(' ')))
#リストに適したループを用いる
for num in array:
print(num)
上記のループでも十分にシンプルになりましたが、更にコード短くするには、ループをたった1行で 表記する内包表記 を用います。
[出力結果のprint文 for リストの要素の変数名 in リスト名]
今回の例ですと、
[print(num) for num in array]
と表記致します。
N=int(input())
array=list(map(int,input().rstrip().split(' ')))
#内包表記を用いた1行のループ
[print(num) for num in array]
Pythonは以上です。 次は、GASで解いて行きます。
■ GASでの解き方 ■
では、同じ問題をGASで解いて行きます。
まず、スプレッドシートにこの様に配置しました。
paizaの問題集側で入力例3 を2行分全てコピーして、スプレッドシート側で灰色のセルB1の所で[Ctrl] + [Shift] + [V] で値のみ貼り付けます。
すると、灰色のセルB1にN=「8」、緑色のセルB2に具体的な数値「8 1 3 8 1 3 8 1」が書式を崩さずにそのまま貼り付けられます。
これをD2から始まる8行の黄色いセルに出力します。
※ スプレッドシートに出力する場合は、二次元配列にして出力します ※
手順は以下の様になります。
1: スプレッドシートからアクティブシートをアクセスする 2: 空の配列arrayを宣言して、数値の個数Nと8個の数値をまとめて、灰色のセルB1(1,2)から2行分arrayに取得する 3: 定数Nにarray[0][0]を代入する 4: splitを用いて残りの配列array[1][0]を半角スペースで分割する 5: スプレッドシート出力用に空の配列array2を宣言して、ループの中でpushを用いてarrayの要素をarray2に二次元配列になる様に追加する。 6: スプレッドシートのD2(2,4)から始まる黄色いセルに出力する
手順1: スプレッドシートからアクティブシートをアクセスする
ss=SpreadsheetApp.getActiveSheet();
関数「loop4」にコードを書いて行きます。
function loop4() {
//スプレッドシートの階層を辿ってアクティブシートにアクセスする
const ss=SpreadsheetApp.getActiveSheet();
}
手順2: 空の配列arrayを宣言して、数値の個数Nと8個の数値をまとめて、灰色のセルB1(1,2)から2行分arrayに取得する
array=ss.getRange(1,2,2).getValues();
セルB1が(1,2)でそこから2行分で(1,2,2)となります。 列数の1列は省略可能です。
2つの数値を取得するので、getValues と複数形のs が付きます。
function loop4() {
const ss=SpreadsheetApp.getActiveSheet();
//空の配列arrayを宣言する
let array=[];
//灰色のセルB1(1,2)から2行分取得して、配列arrayに格納する
array=ss.getRange(1,2,2).getValues();
//取得した配列をログ出力で確認する
console.log(array);
}
出力結果です。
この配列arrayは、array[0][0]が数値の個数「8」で、残りの8個の数値がarray[1][0]になります。
次の手順でarray[0][0]の8を定数Nに代入します。
手順3: 定数Nに配列array[0][0]を代入する
const N=array[0][0];
function loop4() {
const ss=SpreadsheetApp.getActiveSheet();
let array=[];
array=ss.getRange(1,2,2).getValues();
console.log(array);
//個数をNに代入
const N=array[0][0];
//代入されたことをログで確認する
console.log(N);
}
実行後の出力結果です。
この様に、定数Nに8が代入されたことが確認出来ました。 次の手順では、残りの配列array[1][0]を半角区切りの配列arrayにします。
手順4: 残りの配列array[1][0]を半角スペース区切りで数値ごとに分割する
array[1][0]をsplitで半角スペース区切りで分割します。
array=array[1][0].split(‘ ‘);
コードと実行結果です。
function loop4() {
const ss=SpreadsheetApp.getActiveSheet();
let array=[];
array=ss.getRange(1,2,2).getValues();
console.log(array);
const N=array[0][0];
console.log(N);
//残りの数値をsplitで分割する
array=array[1][0].split(' ');
//arrayが半角区切りになっていることをログで確認する
console.log(array);
}
これで、arrayの残りの分が半角スペース区切りで分割出来ました。
手順5:スプレッドシート出力用に空の配列array2を宣言して、ループの中でpushを用いてarrayの要素をarray2に二次元配列になる様に追加する。
for(let i=0;i<N;i++)
カウンタ変数iはループの中で代入される数が変わるのでletで宣言しています。
ループは数値の個数の8が代入されているNをそのまま利用します。 配列は添字が0から始まるので、i<N とすることで、i=0,1,2,3,4,5,6,7の8回分ループを繰り返します。
array2.push([array[i]]);
スプレッドシート出力用のarray2が二次元配列になる様に、pushを用いて追加しています。
[array[i]] とarrayの全体を[ ]で括ることで二次元配列としての追加になります。
下記のコードの実行結果です。
function loop4() {
const ss=SpreadsheetApp.getActiveSheet();
let array=[];
array=ss.getRange(1,2,2).getValues();
console.log(array);
const N=array[0][0];
console.log(N);
array=array[1][0].split(' ');
console.log(array);
//スプレッドシート出力用の空の配列array2を宣言
const array2=[];
//ループを用いてarrayの要素をarray2が二次元配列になる様に追加する
for(let i=0;i<N;i++){
array2.push([array[i]]);
}
//スプレッドシートに出力する前にarray2をログで確認する
console.log(array2);
}
手順6: スプレッドシートのD2(2,4)から始まる黄色いセルに出力する
ss.getRange(2,4,N).setValues(array2);
セルD2が(2,4)でそこから8行分出力するので、Nをそのまま使います。 (2,4,N)で8行分で、1列ですので(2,4,N,1)になりますが、1列は省略可能です。
また、数値の数が8個で複数形ですので、setValues とs が付きます。 コードとスプレッドシートの出力された実行結果です。
function loop4() {
const ss=SpreadsheetApp.getActiveSheet();
let array=[];
array=ss.getRange(1,2,2).getValues();
console.log(array);
const N=array[0][0];
console.log(N);
array=array[1][0].split(' ');
console.log(array);
const array2=[];
for(let i=0;i<N;i++){
array2.push([array[i]]);
}
console.log(array2);
//スプレッドシートのセルD2(2,4)から始まる黄色いセル8行に出力する
ss.getRange(2,4,N).setValues(array2);
}
※ この記事の作成に参考になったサイトです ※ ありがとうございます。
Python mapの使い方 Python rstripの使い方
お疲れ様でした。ブレイクタイムPhotoは、
羽田空港第1ターミナルの展望台の夜景です。
←前の問題へ 次の問題へ→
ご精読有難うございました。■ GASの入門書の紹介です ■ 詳解! Google Apps Script完全入門 [第3版] 単行本 Kindle版(電子書籍)
■ 関連記事 ■ paizaレベルアップ問題集「ループその1の1」へ戻る paizaレベルアップ問題集_PythonとGASのコード紹介トップページへ 写真クリエイターとしての活動 自己紹介