ちゃお・・・†
はじめに
Python でネストしている (入れ子構造になってる) リストを1つのリストにまとめたい、つまり flatten したい時ってたまにありますよね。そうした場合に対処する情報も Web 検索すればすぐ出てきます。でも、それをいちいちコピペするのって正直めんどくさくないですか?わたしはめんどくさい。というわけで、この記事では、Python で flatten するモジュール flati
を紹介します。
現時点では、Python 2.7とPython 3.4~3.13 対応です。Pure-Python モジュールなので、対応しているPython 環境さえあれば、Windows / macOS / Ubuntu など色々なプラットフォームで動くと思います。
名前の由来
flatten 処理と Fulvio Frati 氏 (一緒に研究したことある先生) をかけて flati
と名付けました。わたしは「ふらてぃ」と発音してます。
インストール
$ pip install flati
or
$ python -m pip install flati
使い方
import flati
# flati.flatten 関数は入れ子になってる Iterable オブジェクトを1要素ごとに返すジェネレーターを返します。
# 返却値を1つの Iterable オブジェクトにまとめたい場合は list() などを使ってください。
iterable = [(1, 2, 3), (4, (5, 6))]
list(flati.flatten(iterable))
# => [1, 2, 3, 4, 5, 6]
# 念の為、もう一度書きます。flati.flatten()はジェネレーターです。
import types
isinstance(flati.flatten(iterable), types.GeneratorType)
# => True
# もし、ある特定の Iterable オブジェクトを flatten したくない場合は、"ignore" 引数で指定してください。
iterable = [('abc'), ('def', ('g', 'hi'))]
list(flati.flatten(iterable, ignore=str))
# => ['abc', 'def', 'g', 'hi']
# Version 0.2.1 から str を flatten しない便利な関数 flatten_non_str を追加しました。
# この関数は "flatten(iterable, ignore=str)" と等価です。
iterable = [('abc'), ('def', ('g', 'hi'))]
list(flati.flatten_non_str(iterable))
# => ['abc', 'def', 'g', 'hi']
Tips
もしも NumPy の ndarray
を flatten したい時は、NumPy の関数を使ってください。そっちの方が速いです。
- numpy.ravel()
- コピーを作らないでオブジェクトを変更します。つまり破壊的処理です。
- ndarray.reshape(-1)
- ビューを生成するので、
numpy.ravel()
と同じく高速処理に向いています。個人的にはこれが一番おすすめです。 - ndarray.flatten()
- これはコピー処理を行うので若干遅いですが、破壊的処理でないので元の
ndarray
を保つことが出来ます。
参考: https://python.atelierkobato.com/flat/
先行事例
PyPI で "flatten" をクエリーにして検索して出てきたものを紹介します。dict
型を flatten するものは対象外とします。なお、記述はわたしの私感です。
- flatten-list
- ドキュメントのリンクが切れています。2017年8月でリリースが止まっています。
str
型とbytes
型のみflattenしないようにハードコーディングされています。
- ドキュメントのリンクが切れています。2017年8月でリリースが止まっています。
- flatter
- ドキュメントがありません。2016年8月でリリースが止まっています。ソースコードを見ると何やら複雑な処理を行っているのでオーバーヘッドはどうなんでしょう?
- FlattenList
- 2015年1月でリリースが止まっています。GitHub 等での公開リポジトリがないのが不安かも。
- Flattener
- 2016年3月でリリースが止まっています。
ignore
引数がないのでstr
だけflattenしたくない時などに困るかも。
- 2016年3月でリリースが止まっています。
- flatlist
- 名前の通り
list
型しか対応していません。2018年12月でリリースが止まっています。ドキュメントはしっかりしています。
- 名前の通り
flatiを使うメリット
- flatten 処理を実装するために Web 検索して出てきたコードをコピペしなくて済む
- Iterable なオブジェクトならなんでも OK
-
ignore
引数で flatten したくない型を指定できる - ジェネレーターなので巨大データを扱う場合にメモリ使用量がやさしい
- モジュール名の文字数が少なめ (5文字)
- 実装がシンプル (ソースコード)
- Pure-Pythonモジュールなので気軽に色々なプラットフォームで動く
厚かましいお願い
- もしも気に入ったらflatiのGitHubリポジトリにスターをつけていただくと嬉しいです。たったの1クリックだけで、わたしの開発のモチベーションがアップします。
- スターだけじゃ物足りない!という方は、flatiのGitHubリポジトリの Sponsor ボタンを押すとわたしに物を送ることが出来ます。わたしの開発のモチベーションがかなりアップします。
- リクエストやバグ報告/修正についての Issue と Pull request は日本語でも OK です (題名は英語でお願いします)
さいごに
これから数日間は、とりあえず作ったものの全然宣伝していなかったモジュールとかを紹介していきたいと思います。
震えて待て・・・†