PHPしか知らない僕がPythonを少し触ってみたよ 〜リストをいじくり回す〜

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
ポップコーンはもう何年も食べてない気がする

この記事を三行にまとめると

リストをいろいろいじくり回してみようと思います
エクセレンッ!!( >_<)b
最初に電子レンジで温められた食べ物ってポップコーンらしいっすよ
前回、PHPの配列にあたるリストやディクショナリについてちょっと触れました。今回はそのリストをいろいろいじくり回してみようと思います。

ただ、ちょっと内容がモリモリになってしまったので、今回は主に要素の追加や削除に関することを中心にやります。ソートとかimplode、explodeなどは次回に回します。

ディクショナリについてもまた今度ってことで。



要素を追加する

リストに要素を追加します。

//PHP
$array[] = 'abc';

#Python
array = []
array.append('abc')

PythonのリストはPHPみたく「array[] = ‘abc’」って感じで要素を追加することができません。「append()」という関数を使います。PHPにも「array_push()」という要素を追加できる関数がありますが、あれに近いのかな。「array_push()」と違って二つ以上の要素を一気に追加することはできませんけど。

//PHP
$array[] = 'abc';
array_push($array, 'def', 'ghi'); //いける

#Python
array = []
array.append('abc', 'def', 'ghi') #エラー

複数の要素をまとめて追加したければ後述の「extend()」という関数を使ってください。



先頭に要素を追加

リストの先頭に要素を追加します。PHPの「array_unshift()」に相当するものです。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
array_unshift($array, 'f');

#Python
array = ['a', 'b', 'c', 'd', 'e']
array.insert(0, 'f')

Pythonでは「insert()」という関数を使います。意味合いとしては「リストの0番目にfという要素を追加している」って感じです。

「じゃあ1番目以降もinsert()使えばええんやないの?」って思った方。exactlyです。Pythonにはarray_unshift()のように、先頭に追加するためだけの関数はないっぽいです。



任意の場所に要素を追加

例えばリストの3番目(上の例だとcとdの間)に要素を追加するならこう。

array = ['a', 'b', 'c', 'd', 'e']
array.insert(3, 'f')

これはPHPにはない機能ですね。PHPで任意の場所に追加しようと思ったらメソッドを自作しないといけない。

function array_insert($array, $value, $index) {
  //配列を指定したインデックスのところで分割する
  $tmp = array_chunk($array, $index);

  //分割された前半の要素
  foreach($tmp[0] as $t) {
    $ret[] = $t;
  }

  //追加したい要素
  $ret[] = $value;

  //分割された後半の要素
  foreach($tmp[1] as $t) {
    $ret[] = $t;			
  }

  return $ret;
}

$array = array('a','b','c','d','e');
$array = array_insert($array, 'f', 3);

こんな感じかなぁ?

「array_chunk()」は指定したところで配列を分割する関数です。上記の場合、配列の3番目で分割するように指定しているので、$tmpの中身はこんな感じになる。

Array
(
  [0] => Array
  (
    [0] => a
    [1] => b
    [2] => c
  )

  [1] => Array
  (
    [0] => d
    [1] => e
  )
)

あとはこの$tmpの0番目と1番目の間に追加したい要素(f)を入れるような処理をやれば良いと、そんな感じです。foreachの代わりに「array_merge()」とかを使っても良いと思います。




先頭の要素を取り除く

リストの先頭の要素を取り除きます。PHPで言うところの「array_shift()」です。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
array_shift($array);

#Python
array = ['a', 'b', 'c', 'd', 'e']
array.pop(0)

リストの要素を取り除くには「pop()」という関数を使います。「pop」ってのは「飛び出る」とか「ポンと出る」みたいな意味があるそうで。ポップコーンのポップはここから来てるのかな。ポップ種(ポップコーンに使われるトウモロコシ)って爆裂種とも言うらしいですし。

「0」を指定しているってことはまさか「insert()」と同じ感じなのでは……? と思った人。エクセレンッ!!( >_<)b

array_unshiftと同じように、先頭の要素を取り除くためだけの機能もPythonにはないようなので、要素を取り除くpopをリストの先頭に適用することになります。



任意の要素を取り除く

リストの3番目(上の例で言うとd)を取り除いてみます。PHPだと「unset()」が相当しますかね。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
unset($array[3]);

#Python
array = ['a', 'b', 'c', 'd', 'e']
array.pop(3)

どちらも残った要素は「a,b,c,e」となるのですが、PHPの「unset()」はキーが保持されるのに対し、Pythonの「pop()」はキーがリセットされます。

つまりこういうことです。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
unset($array[3]);
echo $array[3];

//出力結果(エラー)
Undefined offset: 3

#Python
array = ['a', 'b', 'c', 'd', 'e']
array.pop(3)
print(array[3])

#出力結果
e

PHPだとエラーになりますが、Pythonではdが取り除かれたことでeがリストの3番目になっています。



Pythonの場合、「del」というのもあります。

array = ['a', 'b', 'c', 'd', 'e']
del array[3]

結果は同じです。

delは複数の要素をまとめて削除することもできます。

array = ['a', 'b', 'c', 'd', 'e']
del array[0:3]

例えばこんな風に書くと、リストの先頭の三つの要素を一度に削除できます。



最後の要素を取り除く

PHPの「array_pop()」も「pop()」で実現できます。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
array_pop($array);

#Python
array = ['a', 'b', 'c', 'd', 'e']
array.pop()

インデックスを省略して書くと最後の要素が取り除かれます。



要素を指定して取り除く

PHPの「unset()」やPythonの「pop()」「del」はインデックスを指定して要素を削除するものです。じゃあ要素を指定して削除するにはどうするか。

PHPなら「array_search()」と「unset()」を組み合わせるのが良いかしら?

$array = array('a', 'b', 'c', 'd', 'e');
$i = array_search('d', $array);
unset($array[$i]);

これでdを取り除くことができます。

Pythonにはこれをさくっと実現できる「remove()」という関数があります。

array = ['a', 'b', 'c', 'd', 'e']
array.remove('d')

注意したいのは、どちらの場合も指定した要素がない場合、期待した動きをしてくれないってことですね。「array_search()」の場合は指定した要素がないとfalseが返ってくるので、そのまま「unset()」すると先頭の要素が削除されてしまいます。「remove()」は単純にエラーになる。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
$i = array_search('s', $array);//falseが返る
unset($array[$i]); //unset($array[0])と同じ動きになる

#Python
array = ['a', 'b', 'c', 'd', 'e']
array.remove('s') #エラーになる



要素があるか判定する

リストの中に指定した要素があるかどうか判定する方法。PHPの「in_array()」に相当するものです。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
$flg = in_array('s', $array);

#Python
array = ['a', 'b', 'c', 'd', 'e']
flg = 's' in array

上記の場合だとfalseが返ってくるので、if文と絡めればさっきのエラーも回避できますね。

array = ['a', 'b', 'c', 'd', 'e']
if 's' in array:
  array.remove('s')



ちなみに指定の要素がないかどうか確かめたい場合、PHPとPythonではそれぞれこんな書き方になります。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
$flg = !in_array('s', $array);

#Python
array = ['a', 'b', 'c', 'd', 'e']
flg = 's' not in array

PHPだとビックリマークをつければ良いのですが、Pythonでは「not in」と書く必要があります。



今度は指定した要素がリストのどこにあるか知りたい場合。すでに登場済みですが、PHPの「array_search()」に相当するものです。

//PHP
$array = array('a', 'b', 'c', 'd', 'e');
$i = array_search('d', $array);

#Python
array = ['a', 'b', 'c', 'd', 'e']
i = array.index('d')

「remove()」と同じで、指定した要素がない場合は「index()」もエラーになるので、使うときはさっきの「in」を使ってif文でエラーを回避しとくのが良いでしょう。



リストのマージ

最後にリストのマージについて触れときやしょう。appendの時にちょっと触れた「extend」ってのを使います。

//PHP
$array1 = array('a', 'b', 'c');
$array2 = array('d', 'e');
$array = array_merge($array1, $array2);

#Python
array1 = ['a', 'b', 'c']
array2 = ['d', 'e']
array1.extend(array2)

PHPは「array_merge()」の返り値を受け取る必要がありますが、Pythonはその必要はないです。むしろ受け取るような書き方をすると中身がなくなってしまいます。

array1 = ['a', 'b', 'c']
array2 = ['d', 'e']
array1 = array1.extend(array2)

#Noneになる
print(array1)

「array_merge()」は複数の配列を一度に追加できますが、Pythonの「extend()」は一つしか追加できません。

//PHP
$array1 = array('a', 'b', 'c');
$array2 = array('d', 'e');
$array3 = array('f');
$array = array_merge($array1, $array2, $array3);

#Python
array1 = ['a', 'b', 'c']
array2 = ['d', 'e']
array3 = ['f']
array1.extend(array2, array3) #エラー

Pythonで複数のリストを一気に追加したい場合は、単純にプラスで足し合わせる方法があります。

array1 = ['a', 'b', 'c']
array2 = ['d', 'e']
array3 = ['f']
array = array1 + array2 + array3

これでarrayの中身は[‘a’,’b’,’c’,’d’,’e’,’f’]になります。






今回はここまでです。

要素を削除する方法としては他に「array_unique()」がありますが、それは次回に回します。ちょいとソートを話に絡めなきゃいけない部分があるもので。

そういえば、世界で最初に電子レンジで温められた食べ物ってポップコーンらしいっすよ。二番目はニワトリの卵だという噂だが……まあ実験に失敗はつきものですからね。



その他のPythonを少し触ってみたの記事はこちら
前書きと索引的な
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください