【Python】リスト(list)の操作

今回は、よく使うリストの操作について解説します。

特にリストからインデックスを取得し、次の要素に移動するとか、2つ前の要素に移動するなど複雑な処理ができるようになります。

 

 

リストとは

リストとは、[](カギ括弧)の中に要素が入っていて、,(カンマ)で区切ります。

 

【リストの例】

['りんご', 'みかん', 'ぶどう', 'なし', 'すいか', 'いちじく']

 

上のリストは果物が入ったリストです。

リストの要素1つ1つに果物(りんごとかみかん)が入っています。

上のリストの例では、要素数は「6」個です。

 

 

リストに要素を追加したい

■構文

リスト.append('要素')

 

■プログラム例

list01 = ['うみ','かわ','やま']

 

list01.append('もり')

 

 

■プログラム実行

(pyenv) [test@SAKURA_VPS scraping]$ python test6.py
['うみ', 'かわ', 'やま', 'もり']
(pyenv) [test@SAKURA_VPS scraping]$

 

 

テキストファイルを改行ごとにリストにしたい

split関数で「\n(改行)」を指定することで、改行ごとに1要素としてリストに格納されます。

f = open('test.txt', 'r')
lines = f.read().split('\n') 

print(lines)

 

 

【例】プログラム

(pyenv) [test@SAKURA_VPS scraping]$ cat test1.py
# -*- coding: utf-8 -*-

 

f = open('test.txt', 'r')
lines = f.read().split('\n')

print(lines)
(pyenv) [test@SAKURA_VPS scraping]$

 

 

【例】テキストファイル

(pyenv) [test@SAKURA_VPS scraping]$ cat test.txt
りんご
みかん
ぶどう
なし
すいか
いちじく

 

(pyenv) [test@SAKURA_VPS scraping]$

 

 

【実行結果】

(pyenv) [test@SAKURA_VPS scraping]$ python test1.py
['りんご', 'みかん', 'ぶどう', 'なし', 'すいか', 'いちじく', '', '']
(pyenv) [test@SAKURA_VPS scraping]$

 

リスト形式で出力されています。

 

【疑問点】なぜ要素が1つ多くなる?【追記 2017年12月9日】

最初は気が付かなかったのですが、よくよく見返してみると要素数が1つ多くなっています。

 

【例】テキストファイル

(pyenv) [test@SAKURA_VPS scraping]$ cat test.txt
りんご
みかん
ぶどう
なし
すいか
いちじく

      ← ここに空行が1つあります。

(pyenv) [test@SAKURA_VPS scraping]$

 

【実行結果】

(pyenv) [test@SAKURA_VPS scraping]$ python test1.py
['りんご', 'みかん', 'ぶどう', 'なし', 'すいか', 'いちじく', '', ''] ← なぜか空の要素が2つになっています。
(pyenv) [test@SAKURA_VPS scraping]$

 

 

一見すると空の要素が1つ増えただけで問題ないように見えますが、後々これがバグになりトラブルを引き起こす原因になりそうです。

 

 

splitメソッド

splitメソッドは何も難しい所はなくて、単純に文字列を任意の区切り文字で区切り、リストに格納するだけのメソッドです。

 

■splitメソッドの構文

'文字列'.split('区切り文字')

 

 

しかしどこから謎の空の要素が出てきたのでしょうか?

 

【プログラム】

(pyenv) [test@SAKURA_VPS scraping]$ cat test.py
# -*- coding: utf-8 -*-

# ファイルをオープンして果物を配列(リスト)に代入する
f = open('test.txt', 'r')
fruits_list = f.read().split('\n')
print(fruits_list)

print('リストの要素数')
print(len(fruits_list))

 

 

【ファイルの中身】

(pyenv) [test@SAKURA_VPS scraping]$ cat test.txt
りんご
みかん
ぶどう
なし
いちじく
いちご
すいか
もも
メロン
(pyenv) [test@SAKURA_VPS scraping]$ 

 

 

【プログラム実行結果】

(pyenv) [test@SAKURA_VPS scraping]$ python test.py
['りんご', 'みかん', 'ぶどう', 'なし', 'いちじく', 'いちご', 'すいか', 'もも', 'メロン', ''] ← やはり空の要素が1つ出来ます。
リストの要素数
10
(pyenv) [test@SAKURA_VPS scraping]$

 

 

splitメソッドは区切り文字を入れるとおかしな動作になるので注意

試しに区切り文字を入れずに split() のままで実行してみます。

 

【プログラム例】

(pyenv) [test@SAKURA_VPS scraping]$ cat test.py
# -*- coding: utf-8 -*-

# ファイルをオープンして果物を配列(リスト)に代入する
f = open('test.txt', 'r')

# 改行コードで分割することを明示
fruits_list = f.read().split('\n')
print(fruits_list)

print('リストの要素数')
print(len(fruits_list))

# ファイルをオープンして果物を配列(リスト)に代入する
f = open('test.txt', 'r')

# 改行コードで分割することを明示しない場合
fruits_list = f.read().split()
print(fruits_list)

print('リストの要素数')
print(len(fruits_list))

 

 

【実行結果】

(pyenv) [test@SAKURA_VPS scraping]$ python test.py
['りんご', 'みかん', 'ぶどう', 'なし', 'いちじく', 'いちご', 'すいか', 'もも', 'メロン', '']
リストの要素数
10
['りんご', 'みかん', 'ぶどう', 'なし', 'いちじく', 'いちご', 'すいか', 'もも', 'メロン']
リストの要素数
9
(pyenv) [test@SAKURA_VPS scraping]$

 

これは「謎」です。

 

 

  • 分割文字指定 ← 謎の空要素ができる
  • 分割文字指定なし ← 空要素はできない

 

splitメソッドを解説しているサイトを見ると、大体「,(カンマ)」区切りの前提で解説をしているから、逆に「改行」区切りで分割したいケースはないということでしょうか。

カンマ区切りだと、

  • 分割文字指定 ← 謎の空要素はできない
  • 分割文字指定なし ← 空要素はできない

です。

 

Python のドキュメントを読んでみた

意味が分からないため、Python のドキュメントを読んでみました。

 

Python ドキュメント 4. 組み込み型¶(原文)

https://docs.python.jp/3/library/stdtypes.html#str.split

 

そしたらこんな記述がありました。

maxsplit が与えられていれば、最大で maxsplit 回分割されます (つまり、リストは最大 maxsplit+1 要素になります)。」

 

これでしょうか。

つまり、split('\n')というように区切り文字を指定すると、リストの要素数が maxspilit +1となり、合計10個となる。。

しかしカンマだとならないのはなぜでしょうか。

 

 

【原因解明】「復帰改行」か「改行」の違いだった

原因解決しました。

catコマンドで改行コードを調べてみたところ、一番最後の行の後ろにちゃんと「改行」コードが含まれていました。

 

  • 改行コード(LF) ← $
  • 改行コード(CR) ← ^M
  • 改行コード(CRLF) ← ^M$

 

(pyenv) [test@SAKURA_VPS scraping]$ cat -n test.txt
     1  りんご
     2  みかん
     3  ぶどう
     4  なし
     5  いちじく
     6  いちご
     7  すいか
     8  もも
     9  メロン
(pyenv) [test@SAKURA_VPS scraping]$ cat -ne test.txt
     1  M-cM-^BM-^JM-cM-^BM-^SM-cM-^AM-^T$
     2  M-cM-^AM-?M-cM-^AM-^KM-cM-^BM-^S$
     3  M-cM-^AM-6M-cM-^AM-)M-cM-^AM-^F$
     4  M-cM-^AM-*M-cM-^AM-^W$
     5  M-cM-^AM-^DM-cM-^AM-!M-cM-^AM-^XM-cM-^AM-^O$
     6  M-cM-^AM-^DM-cM-^AM-!M-cM-^AM-^T$
     7  M-cM-^AM-^YM-cM-^AM-^DM-cM-^AM-^K$
     8  M-cM-^BM-^BM-cM-^BM-^B$
     9  M-cM-^CM-!M-cM-^CM--M-cM-^CM-3$ ←9行目の一番最後にも改行コードが付いていました。
(pyenv) [test@SAKURA_VPS scraping]$

 

これは分かりませんでした。

バグなのか仕様なのか悩みましたが、splitメソッド的には正しい動きでした。

 

split メソッドとしては、「\n(改行コード)」が区切り文字で指定されているので、9行目の「$(LF)」を確認して空の要素を追加していただけだったのです。

 

 

 

 

リストの各要素に番号を付けて縦に出力したい

リストの各要素に番号を付けて縦に出力させる方法です。

リストの要素数は?

リストの要素数は

len(リスト名) 【例】len(lines) など

で取得できます。

 

【プログラム例】

(pyenv) [test@SAKURA_VPS scraping]$ cat test1.py
# -*- coding: utf-8 -*-

f = open('test.txt', 'r')
lines = f.read().split('\n')
print(lines)

print('リストの要素数')
print(len(lines)) ← リストの要素数を出力します。
(pyenv) [test@SAKURA_VPS scraping]$

 

 

【実行結果】

(pyenv) [test@SAKURA_VPS scraping]$ python test1.py
['りんご', 'みかん', 'ぶどう', 'なし', 'すいか', 'いちじく', '', '']
リストの要素数
8 ← 空の要素も含まれています。
(pyenv) [test@SAKURA_VPS scraping]$

 

 

リスト操作の「enumerate」を使うとインデックスを取得できる

enumerate を使うと要素のインデックスを取得できます。

 

enumerate ← 【動詞】~を列挙する。~を数え上げる。

 

【プログラム例】

(pyenv) [test@SAKURA_VPS scraping]$ cat test1.py
# -*- coding: utf-8 -*-

f = open('test.txt', 'r')
lines = f.read().split('\n')
print(lines)

print('リストの要素数')
print(len(lines))

print('リストの各要素のインデックスと要素を並べて出力させる')
for index, value in enumerate(lines):
    print(index,value)
(pyenv) [test@SAKURA_VPS scraping]$

 

 

【実行結果】

(pyenv) [test@SAKURA_VPS scraping]$ python test1.py
['りんご', 'みかん', 'ぶどう', 'なし', 'すいか', 'いちじく', '', '']
リストの要素数
8
リストの各要素のインデックスと要素を並べて出力させる
0 りんご
1 みかん
2 ぶどう
3 なし
4 すいか
5 いちじく
6
7
(pyenv) [test@SAKURA_VPS scraping]$

 

range を使っても enumerate と同様のことができますが、構文が若干複雑になります。

(一見しただけでは何をしているのか直感的に分かりにくくなる)

 

そのため分かりやすい「enumerate」がお勧めです。

enumerate」の意味は「数え上げる」と覚えておけばすぐに何をしているのか分かるようになります。

 

 

 

 

 

Posted by 100%レンタルサーバーを使いこなすサイト管理人

コメントを残す

メールアドレスが公開されることはありません。