Go言語のスライスの基本に続いて、スライスの操作についていくつかここから見て行きます。
少し既に触れた部分もありますが、ここではappendとrangeを扱います。
appendではスライスでの追加と削除を、rangeはfor文と合わせてループ処理を行って見ます。
スライスとappend
スライスの基礎のところでも少し触れましたが、Go言語のスライスに値を追加するにはappendを使って次のように行います。
package main
import (
"fmt"
)
func main() {
x := []int{1, 2, 3, 4, 5}
fmt.Println(x)
x = append(x, 6, 7, 8, 9, 10)
fmt.Println(x)
}
これは前に触れた形と同じです。append()の第1引数にスライスを、第2引数以下に追加する値をとっています。複数の値を渡すことができるのが特徴です。
結果は次のとおり。
[1 2 3 4 5]
[1 2 3 4 5 6 7 8 9 10]
では、このスライスに別のスライスを追加する形はどうなるでしょうか?
次のコードでやってみます。
package main
import (
"fmt"
)
func main() {
x := []int{1, 2, 3, 4, 5}
fmt.Println(x)
y := []int{100, 200, 300, 400, 500}
x = append(x, y)
fmt.Println(x)
}
appendを使ってyのスライスを追加しているのがわかります。
ただこれは、実行すると次のようにエラーになります。
cannot use y (type []int) as type int in append
これは次のようにすることで、値を追加することが出来ます。
package main
import (
"fmt"
)
func main() {
x := []int{1, 2, 3, 4, 5}
fmt.Println(x)
y := []int{100, 200, 300, 400, 500}
x = append(x, y...)
fmt.Println(x)
}
先ほどのコードとの違いがわかるでしょうか? appendに追加した「y」のところが「y…」になっているのがわかります。
このように、スライスをappendで追加する時は「…」を後ろに加えます。
実行してみます。
[1 2 3 4 5]
[1 2 3 4 5 100 200 300 400 500]
今度は追加出来ているのがわかります。
appendを使っての削除
今度はスライスの削除をappendを使ってやってみましょう。
これはコロンで範囲指定を組み合わせて行います。
先ほどのコードを使ってやってみましょう。
package main
import (
"fmt"
)
func main() {
x := []int{1, 2, 3, 4, 5}
fmt.Println(x)
y := []int{100, 200, 300, 400, 500}
x = append(x, y...)
fmt.Println(x)
x = append(x[:3], x[7:]...)
fmt.Println(x)
}
appendコロンを使ったスライスで範囲を限定しているのがわかります。
また、第2引数には先ほどと同じように「…」を使っているのがわかります。
実行するとこうなります。
[1 2 3 4 5]
[1 2 3 4 5 100 200 300 400 500]
[1 2 3 300 400 500]
指定範囲で出力されることで、値が削除されているのがわかります。
スライスとrange
今度は、rangeを使ってスライスの値をループする方法について見て行きましょう。これには、for文と組み合わせて使います。
次のようなコードになります。
package main
import (
"fmt"
)
func main() {
x := []int{1, 2, 3, 4, 5}
fmt.Println(len(x))
fmt.Println(x)
for i, v := range x {
fmt.Println(i, v)
}
}
前半のコードはスライスの初期化と、データの長さを確認しているだけです。
後半のfor文について、rangeでスライスxから、インデックスのiと、値のvを取り出すという処理をしています。
実行するとこうなります。
5
[1 2 3 4 5]
0 1
1 2
2 3
3 4
4 5
ここで、インデックスの表示が必要無い時はどうするか触れておきましょう。
for文でiを使わずに、アンダースコア(_)を使ってコードを書きます。こうすると、インデックスの値を無視することが出来ます。
コードで書くと次のようになります。
package main
import (
"fmt"
)
func main() {
x := []int{1, 2, 3, 4, 5}
for _, v := range x {
fmt.Println(v)
}
}
iをアンダースコアで省略しています。
出力はvのみの処理をしています。
結果は次の通り。
1
2
3
4
5
値のみがループ処理されているのが確認出来ます。
Pythonコードで書くと…
Pythonで同じようなコードを書いてみましょう。
Pythonの場合はリストで行います。リストをappendで追加してみます。
def main():
x = [1, 2, 3, 4, 5]
y = [6, 7, 8, 9, 10]
x.append(y)
print(x)
if __name__ == "__main__":
main()
リストxにappendでリストyを追加しています。
実行するとこうなります。
[1, 2, 3, 4, 5, [6, 7, 8, 9, 10]]
リスト自体が追加されているので、Goのスライスの追加とかちょっと違っています。
リストの値を追加するには、次のようにextendを使うと可能になります。
def main():
x = [1, 2, 3, 4, 5]
y = [6, 7, 8, 9, 10]
x.extend(y)
print(x)
if __name__ == "__main__":
main()
こうすると、Goと同じような処理になります。appendでひとつづつ値を追加する方法よりもコード量が少なくなりますね。
結果はこうなります。
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
リストが結合されて、値が表示されているのがわかります。
Goのスライスとrangeの使い方と同じようにはPythonのリストでは使え無い感じですね。
最後に
ここでは、Go言語のスライス(Slice)に、append、rangeを使って操作する方法を見てきました。
appendを使えば値を追加することが出来ますが、スライスを追加する場合は、追加するスライスの変数に「…」を加えて利用します。
appendにコロンでの範囲を指定することで、値の削除をすることが出来ます。
rangeをfor文と共に使うことで、インデックスと値を取り出してループ処理することが出来ます。