第17回.リスト内包表記
Pythonではリストを生成する方法の1つとしてリスト内包表記があります。
リスト内包表記を使うと1行でシンプルに書くことが出来ます。
ただし分かりづらいところがあり慣れが必要だと思います。
繰り返し練習が必要になると思うので、以下ではスクリプトをコピーして簡単に実行できるようにしました。
目次
リスト内包表記の基本
基本構文
リスト変数 = [式 for 変数 in イテラブル]
式で評価した結果でリスト生成します。
上記は次のfor文と互換になります。
リスト変数 = []
for 変数 in イテラブル:
リスト変数.append(式)
ary = [i * 2 for i in range(5)]
print(ary)
ary = []
for i in range(5):
ary.append(i * 2)
print(ary)
変数 i のスコープが内包表記内に閉じている点も大きい利点です。
上記はlambda(ラムダ式)で書くこともできます。
ary = list(map(lambda n:n * 2, range(5)))
print(ary)
リスト内包表記の条件分岐
基本構文
リスト変数 = [式 for 変数 in イテラブル if 条件式]
イテラブル(シーケンス等のイテラブルオブジェクト)から要素を1つずつ取り出し、
条件式がTrueの値だけを最初の式で評価しリスト生成します。
これは次のfor文と互換になります。
リスト変数 = []
for 変数 in イテラブル:
if 条件式:
リスト変数.append(式)
print(subs)
print(ary)
文字列の一部に"a"or"A"の文字を含むもの
lang = ["Python","VBA","GAS","Java","C","JavaScript"]
subs = [s for s in lang if "a" in s.lower()]
print(subs)
s.lower()で小文字に変換した結果の文字列に"a"が入っていればTrue。
Trueの場合だけリスト生成されます。
lang = ["Python","VBA","GAS","Java","C","JavaScript"]
subs = []
for s in lang:
if "a" in s.lower():
subs.append(s)
print(subs)
lang = ["Python","VBA","GAS","Java","C","JavaScript"]
subs = filter(lambda s:s if "a" in s.lower() else None, lang)
print(list(subs))
第15回.lambda(ラムダ式、無名関数)と三項演算子
3の倍数だけ抜き出す
#リスト内包表記
ary = [i for i in range(1,11) if i % 3 == 0]
print(ary)
#for文
ary = []
for n in range(1, 11):
if n % 3 == 0:
ary.append(n)
print(ary)
#ラムダ式とfilter()関数
ary = list(filter(lambda i:i if i % 3 == 0 else None, range(1,11)))
print(ary)
3の倍数は3倍、以外は2倍
#リスト内包表記
ary = [i * 3 if i % 3 == 0 else i * 2 for i in range(1,11)]
print(ary)
#for文
ary = []
for n in range(1,11):
if n % 3 == 0:
ary.append(n * 3)
else:
ary.append(n * 2)
print(ary)
#ラムダ式とmap関数
ary = list(map(lambda i:i * 3 if i % 3 == 0 else i * 2, range(1,11)))
print(ary)
リスト内包表記の複数for文
基本構文
リスト変数 = [式 for 変数1 in イテラブル1 for 変数2 in イテラブル2]
リスト変数 = [式 for 変数1 in イテラブル1
for 変数2 in イテラブル2]
リスト変数 = []
for 変数1 in イテラブル1:
for 変数2 in イテラブル2:
リスト変数.append(式)
2つのシーケンスの掛け合わせ
ary = [(x, y) for x in range(1, 4) for y in range(1, 3)]
print(ary)
ary = []
for x in range(1, 4):
for y in range(1, 3):
ary.append((x, y))
print(ary)
(x, y)
これを
[x, y]
このようにすれば、リストの中にリストが入ります。
3重ループ
s = "VBA"
combi = [x+y+z for x in s for y in s for z in s if x != y != z != x]
print(combi)
文字組み合わせのうち同じ文字が使われていないもののみリスト生成しています。
以下と同じです。
s = "VBA"
combi = []
for x in s:
for y in s:
for z in s:
if x != y != z != x:
combi.append(x+y+z)
print(combi)
リスト内包表記のネスト
ただし、最後のzip()関数と引数リストのアンパックの部分が分かりづらいので、
この下のzip()関数とリスト内包表記の中で解説しています。
row, col = 5, 4
#2次元配列作成
ary2 = [[(r - 1) * col + c for c in range(1, col + 1)] for r in range(1, row + 1)]
print(ary2)
#1次元配列に変換
ary1 = [c for r in ary2 for c in r]
print(ary1)
#2次元配列に変換
ary2 = [ary1[i:i + col] for i in range(0, len(ary1), col)]
print(ary2)
後ろに書いたループ1件ずつに対して、前半の内包表記が動きます。
左に書いたループ1件ずつに対して、後半の内包表記が動きます。
row, col = 5, 4
#2次元配列作成
ary2 = []
for r in range(1, row + 1):
ary2.append([])
for c in range(1, col + 1):
ary2[r-1].append((r - 1) * col + c)
print(ary2)
#1次元配列に変換
ary1 = []
for r in ary2:
for c in r:
ary1.append(c)
print(ary1)
#2次元配列に変換
ary2 = []
for i in ary1:
if i % col == 1:
ary2.append(ary1[i-1:i-1+col])
print(ary2)
zip()関数とリスト内包表記
zip()関数
このイテレータは、入力イテラブルの中で最短のものが尽きたときに止まります。
単一のイテラブル引数が与えられたときは、1要素のタプルからなるイテレータを返します。
引数がなければ、空のイテレータを返します。
s = "Python"
combi = [(s1, s2) for s1, s2 in zip(s, s[::-1])]
print(combi)
以下と同じです。
combi = []
for s1, s2 in zip(s, s[::-1]):
combi.append((s1, s2))
print(combi)
公式ドキュメントのネストしたリストの内包表記の後半部分の解説
以下は抜粋です。
matrix = [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]]
list(zip(*matrix))
リストの要素1つずつが別々の引数(ここでは3つ)に展開されます。
そして、その3つの引数をzip()関数に渡しています。
つまり、
zip([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12])
このように指定したものと同じになります。
zip()関数は、3つのリストから要素をあつめます。
最初は、1,5,9、そして次は、2,6,10、・・・
enumerate()関数とリスト内包表記
for count, char in enumerate("Python"):
print(str(count) + "番目の文字は"+char)
[print(str(count) + "番目の文字は"+char) for count, char in enumerate("Python")]
printせずに単純にリスト生成だけなら、分かり易いと思います。
[(count, char) for count, char in enumerate("Python")]
その他の内包表記
集合(set型)
{i for i in range(1, 11)}
今後シリーズが進む過程の中で説明していく予定です。
通常の用途には、帰属テスト、シーケンスからの重複除去、積集合、和集合、差集合、対称差 (排他的論理和) のような数学的演算の計算が含まれます。
辞書(dict型)
{i: c for i, c in zip((1,2,3,4,5),"ABCDE")}
同じテーマ「Python入門」の記事
第14回.関数内関数(関数のネスト)とスコープ
第15回.lambda(ラムダ式、無名関数)と三項演算子
第16回.Pythonの引数は参照渡しだが・・・
第17回.リスト内包表記
第18回.例外処理(try文)とexception一覧
第19回.import文(パッケージ・モジュールのインポート)
第20回.フォルダとファイルの一覧を取得(os,glob,pathlib)
第21回.CSV読み込みとopen()関数とwith文
第22回.CSV読み書き(csvモジュール)
第23回.pipコマンド(外部ライブラリのインストール)
第24回.エクセルを操作する(openpyxl)
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。