0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

python 多次元配列を1次元配列に変換する

Last updated at Posted at 2021-02-23

前回まで分割キーボードを作っていたが完成しやっと手になじんできた。

2次元以上の配列を1次元のリストへ

# 配列返すバージョン
def flatten(x, notype=(str, bytes, bytearray), _recur=False):
    if _recur is False and isinstance(x, notype) or not hasattr(x, "__iter__"):
        return [x]
    return [z for y in x for z in (flatten(y, _recur=True)
              if y is not None and hasattr(y, "__iter__") and not isinstance(y, notype) else (y,))]

# generatorバージョン
def iterflatten(x, notype=(str, bytes, bytearray), _recur=False):
    if _recur is False and isinstance(x, notype) or not hasattr(x, "__iter__"):
        yield x
    yield from (z for y in x for z in (flatten(y, _recur=True)
              if y is not None and hasattr(y, "__iter__") and not isinstance(y, notype) else (y,)))

どんなにネストが深かろうと、1次元配列を返す。
追記 more_itertoolsにcollapseという関数があることを知った。


from more_itertools import collapse
>>> list(collapse([1,2,[3,4,[5,6,[7]]]]))
[1, 2, 3, 4, 5, 6, 7]

>>> flatten([1,2,[3,4,[5,6,[7]]]])
[1, 2, 3, 4, 5, 6, 7]

>>> flatten([1,2])
[1, 2]

# iterableならなんでも回して返す
>>> flatten([1,2,[range(3)]])
[1, 2, 0, 1, 2]

>>> flatten("1,2")
["1,2"]

>>> flatten(None)
[None]

>>> flatten([])
[]

_2d_10000 = [[0, 1, 2]] * 10000

>>> %%timeit
... sum(_2d_10000, [])
466 ms ± 81.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

import itertools

>>> %%timeit
... list(itertools.chain.from_iterable(_2d_10000))
356 µs ± 5.44 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

>>> %%timeit
... flatten(_2d_10000)
9.79 ms ± 31.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# 2次元配列ならitertoolsのfrom_iterableより遅いが、sumより速く、3次元配列以上に対応できる汎用性優位



# 追記 3次元以上
>>> _3nest_10000 = [1,2,[3,4,[5,6,[7]]]] * 10000
>>> from more_itertools import collapse
>>> %%timeit
list(collapse(_3nest_10000))
74.5 ms ± 233 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

>>> %%timeit
flatten(_3nest_10000)
27.7 ms ± 29.3 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?