Python リスト操作関数

Pythonでリスト操作関数をつくりました。
これらの多くはWolfram言語のリスト操作関数のpython版です。
ソースファイルは以下に公開しています。
https://github.com/yoshiF7d/listop
listop のフォルダの一つ上のディレクトリから、import listop とするとlistopを一つのモジュールとして扱えます。

また新しい関数ができたら加筆していこうと思います。

# リストの要素を指定する関数
## part
`part(lst,i)` は `lst` の `i` 番目の要素を返します。
```python
>>> part(['a','b','c','f','e','f'],1)
'b'
```
`part(lst,i,j)` は `lst[i][j]` を返します。
```python
>>> part([['a','b','c'],['d','e','f'],['g','h','i']],1,2)
'f'
```
`part(lst,[i1,i2,...])` は `lst` の `i1`,`i2`,...番目の要素のリストを返します。
```python
>>> part(['a', 'b', 'c', 'd', 'e','f'],[2,4])
['c', 'e']
```
深いレベルリストの指定もできます。
 ```python
>>> part([['a','b'],'c','d'],[[0,1],1])
['b', 'c']
```
## depth
`depth(lst)` は `lst` の深さ（要素を指定するのに必要な添字の数の最大）を返します。
```python
>>> depth(['a'])
1
>>> depth(['a','b'])
1
>>> depth(['a',['b']])
2
```
## indices
`indices(lst,lspec)` は `lspec` で指定されたレベルのサブリストの添字のリストを返します。 
|`lspec` の指定  |  |
|:-----------|------------:|
| n       | レベル 1 から n |
| 0     | すべてのレベル|
| [n]       | レベル n のみ|
| [n1,n2]        |レベル n1 から n2|

正のレベル `n` は `n` 個の添字で指定される要素です。
負のレベル `n` は深さ `n` の要素です。
`indices(lst,[-1])` は `lst` のすべての末端要素を返します。

```python
>>> indices(['a',['b',['c','d']]],[-1])
[[0], [1, 0], [1, 1, 0], [1, 1, 1]]
>>> indices(['a',['b',['c','d']]],[2])
[[1, 0], [1, 1]]
>>> indices(['a',['b',['c','d']]],2)
[[0], [1, 0], [1, 1], [1]]
>>> indices(['a',['b',['c','d']]],0)
[[0], [1, 0], [1, 1, 0], [1, 1, 1], [1, 1], [1]]
```

## level
`level(lst,lspec)` は `lspec` で指定されたレベルのサブリストのリストを返します。 `lspec` は `indices` と同じです。

```python
>>> level(['a',['b',['c','d']]],[-1])
['a', 'b', 'c', 'd']
>>> level(['a',['b',['c','d']]],[2])
['b', ['c', 'd']]
>>> level(['a',['b',['c','d']]],2)
['a', 'b', ['c', 'd'], ['b', ['c', 'd']]]
>>> level(['a',['b',['c','d']]],0)
['a', 'b', 'c', 'd', ['c', 'd'], ['b', ['c', 'd']]]
```

# 構造操作関数
## aslist
`aslist(x)` は `x` がリストのとき`x`をそのまま返し、リストでないとき、`[x]` を返します。
```python
>>> aslist(42)
[42]
```
```python
>>> aslist([1, 2, 3])
[1, 2, 3]
```

## unlist
`unlist(x)` は `x` が単一要素からなるリストのときその要素を返します。それ以外は `x` を返します。

```python
>>> unlist([42])
42
```
```python
>>> unlist([1, 2, 3])
[1, 2, 3]
```
```python
>>> unlist(42)
42
```
## prepend
リストの前に要素を追加したリストを返します。
```python
>>> prepend(['a','b','c','d'],'x')
['x','a','b','c','d']
```
## flatten
`flatten(lst)` はネストされたリストを一次元のリストにします。
```python
>>> flatten([['a', 'b'], ['c', ['d'], 'e'], ['f', ['g', 'h']]])
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
```
`flatten(lst,n)` は レベル `n` までのリストのネストを解消します。
```python
>>> flatten([['a', 'b'], ['c', ['d'], 'e'], ['f', ['g', 'h']]],1)
['a', 'b', 'c', ['d'], 'e', 'f', ['g', 'h']]
```
## partition
`partition(lst,n)` は `lst` を長さ `n` のリストに分割します。
```python
>>> partition(['a','b','c','d','e'],2)
[['a', 'b'], ['c', 'd']]
```
`partition(lst,n,tail=True)` は `lst` は長さ `n` のリストに分割しますが、最後に余った要素も含めます。
```python
>>> partition(['a','b','c','d','e'],2,tail=True)
[['a', 'b'], ['c', 'd'], ['e']]
```

`partition(lst,n,d)` は `lst` を `d` ずつずらした長さ `n` のリストに分割します。
```python
>>> partition(['a','b','c','d','e','f','g'],3,1)
[['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e'], ['d', 'e', 'f'], ['e', 'f', 'g']]
```
## length
`length(lst)` は `lst` の長さを返します。 `lst` がリストでないとき、0 を返します。
```python
>>> length([1,2,3])
3
```
```python
>>> length(1)
0
```
## shape
`shape(lst)` は `lst` の次元を返します。
```python
>>> shape([['a','b','c'],['d','e','f']])
[2, 3]
```

## reshape
`reshape(lst,shape)` は `lst` から次元 `shape` のネストされたリストを返します。

```python
>>> reshape(['a','b','c','d','e','f'],[2,3])
[['a', 'b', 'c'], ['d', 'e', 'f']]
```

```python
>>> reshape(list(range(24)),[2,3,4])
[[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]
```

`reshape(lst,shape,pad)` は `lst` の要素が足りないとき `pad` を使います。

```python
>>> reshape(['a','b','c','d','e','f'],[4,3],'x')
[['a', 'b', 'c'], ['d', 'e', 'f'], ['x', 'x', 'x'], ['x', 'x', 'x']]
```
## transpose
`transpose(lst)` は `lst` のはじめの２つのレベルを入れ替えます。`lst` が行列のとき、転置行列を作ります。
```python
>>> transpose([['a','b','c'],['x','y','z']])
[['a', 'b'], ['c', 'x'], ['y', 'z']]
```
```python
>>> a = reshape(list(range(24)),[2,3,4])
>>> a
[[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]
>>> shape(a)
[2, 3, 4]
>>> b = transpose(a,[0,2,1])
>>> b
[[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]], [[12, 13, 14], [15, 16, 17], [18, 19, 20], [21, 22, 23]]]
>>> shape(b)
[2, 4, 3]
```
## gather
`gather(lst)` は リストの同じ要素をまとめたサブリストのリストを返します。
```python
>>> gather(['a', 'b', 'a', 'd', 'b'])
[['a', 'a'], ['b', 'b'], ['d']]
```
## tally
`tally(lst)` は `lst` の個別要素と重複数のセットのリストを返します。

```python
>>> tally(['a','a','b','a','c','b','a'])
[['a', 4], ['b', 2], ['c', 1]]
```
# 関数をリストに適用する関数
## map
`map(f,lst)` は `lst` の要素に `f` を作用させます。
```python
>>> map(str.upper,['a','b','c'])
['A', 'B', 'C']
```
`map(f,lst,lspec)` は `lst` の `lspec` で指定される要素に `f` を作用させます。`lspec` は `indices` と同じです。
```python
>>> map(str.upper,['a',['b','c']],[2])
['a', ['B', 'C']]
>>> map(str.upper,['a','b',['b','c'],'d'],[-1,1])
['A', 'B', ['b', 'c'], 'D']
```

`map(f,lst,unpack=True)` は `f` を適用するときにリストをアンパックします。 
```python
>>> map(lambda a,b:a+b,[['a', 'b'], ['c', 'd'], ['e', 'f']],unpack=True)
['ab', 'cd', 'ef']
```
`map` は デフォルトで入力で受け取った `lst` を書き換えず、新しいリストを生成します。
`map(f,lst,inpalce=True)` は 入力で受け取った `lst` を書き換えます。

## mapat
`mapat(f,lst,n)` は `f` を `lst` の `n` 番目の要素に作用させます。`n` が負のときはリストの後ろから数えます。
```python
>>> mapat(str.upper,['a','b',['c','d']],1)
['a', 'B', ['c', 'd']]
```
`mapat(f,lst,[i,j,...])` は `f` を `lst[i][j]...` の要素に作用させます。
```python
>>> mapat(str.upper,['a','b',['c','d']],[2,0])
['a', 'b', ['C', 'd']]
```
`mapat(f,lst,[[i1,j1,...],[i2,j2,...]])` は `f` を複数の要素に作用させます。
```python
>>> mapat(str.upper,['a','b',['c','d']],[0,[2,0]])
['A', 'b', ['C', 'd']]
```
# 集合としてのリスト操作関数

## intersection
`intersection(lst_1,lst_2,...)` は `lst_i` のすべてに共通する要素のソートされたリストを返します。
```python
>>> intersection([1,1,2,3],[3,1,4],[4,1,3,3])
[1, 3]
```
## complement
`complement(e_all,e_1,e_2,....)` は `e_all` のうち、どの `e_i` にも含まれない要素のリストを返します。
```python
>>> complement(['a','b','c','d','e'],['a', 'c'], ['d'])
['b','e']
```
## union
`union(lst)`　は　`lst` に含まれる独立した要素のソートされたリストを返します。
```python
>>> union([1,2,1,3,6,2,2])
[1, 2, 3, 6]
```
`union(lst_1,lst_2,...)` はそれぞれの `lst_i` に含まれる独立した要素のソートされたリストを返します。
```python
>>> union(['a','b','c','d'],['d','a','e','b'],['c','a'])
['a', 'b', 'c', 'd', 'e']
```