私が Python で書くとき、私はいつも F# を使っているかのように代替案を考えようとします:
ここでseq
はタプル(key, value1, value2, ...)
を単純化して、長さ 2 だけにしています。キーには重複した数字が含まれています。
let xs = Seq.zip [|1;2;2;3;3;3;4;1;1;2;2|] {0..10} // so this is a seq of tuple
[(1, 0),
(2, 1),
(2, 2),
(3, 3),
(3, 4),
(3, 5),
(4, 6),
(1, 7),
(1, 8),
(2, 9),
(2, 10)]
ここで、 を入力として受け取り、元の seq のサブセットである をseq
返す関数を作成したいと思います。seq
キーが変更されたすべてのアイテムをキャプチャし、最初と最後のアイテムがseq
まだ存在しない場合はそれらを含める必要があります。
f1(xs) = [(1, 0), (2, 1), (3, 3), (4, 6), (1, 7), (2, 9), (2, 10)]
f1([]) = []
以下は私のpythonコードです。動作しますが、あまり好きではありません。
xs = zip([1,2,2,3,3,3,4,1,1,2,2], range(11))
def f1(xs):
if not xs:
return
last_a = None # I wish I don't have to use None here.
is_yield = False
for a, b in xs:
if a != last_a:
last_a = a
is_yield = True
yield (a, b)
else:
is_yield = False
if not is_yield:
yield (a, b) # Ugly, use variable outside the loop.
print list(f1(xs))
print list(f1([]))
itertools
ライブラリを使用する別の方法を次に示します。
def f1(xs):
group = None
for _, group_iter in itertools.groupby(xs, key = lambda pair: pair[0]):
group = list(group_iter)
yield group[0]
# make sure we yield xs[-1], doesn't work if xs is iterator.
if group and len(group) > 1: # again, ugly, use variable outside the loop.
yield group[-1]
F# では、PythonSeq.groupBy
とは動作が異なります。groupby
この問題を可能な限り機能的に解決し、参照セルを減らしmutable
、 を減らし、あまり手間をかけずに解決するにはどうすればよいか疑問に思っています。