2

例: リストが[1,2,3,4,5,6,7,8]あり、それを 20 の長さに「伸ばす」必要があり、既存の値をできるだけ均等に分散させ、「欠落している」値を置き換えNone、結果のリストは 1 で始まり 8 で終わる必要があります。

元のリストの値と 20-8 個の None 値の間には 8-1 個のスペースがあるため、すべての「スペース」に 1 個の None を配置できます。

[1, None, 2, None, 3, None, 4, None, 5, None, 6, None, 7, None, 8]

これで、まだ 12 ~ 7 個Noneの値を配布する必要があり、そのうちの 4 個を 1 つおきのスペースに配布できます。

[1, None, None, 2, None, 3, None, None, 4, None, 5, None,None 6, None, 7, None,
    None, 8]

これで、ランダムに割り当てることができるものが 1 つ残っています。

[1, None, None, 2, None, 3, None, None, 4, None, 5, None, None, 6, None, None 7, 
    None, None, 8]

このようなタスクを実行できるアルゴリズムはありますか? たぶん実装?

4

3 に答える 3

8

基本的な考え方: 古い位置から新しい位置を線形補間するだけです。簡単にするために、フロア除算を使用しますが、巧妙に丸め除算を使用して、分散をもう少し均等にすることもできます。

def stretch_to(l, n):
    out = [None] * n
    m = len(l)
    for i, x in enumerate(l):
        out[i*(n-1)//(m-1)] = x

    return out

サンプル:

>>> stretch_to(range(8), 20)
[0, None, 1, None, None, 2, None, None, 3, None, 4, None, None, 5, None, None, 6, None, None, 7]
于 2012-10-20T19:44:14.467 に答える
4

最初のリストに n 回、2 番目のリストに m 個のアイテムがある場合。このようなものが機能します。

l2 = [None for I in range(m)]
for i, x in emumerate(l1):
    index = i * m / n
    l2[index] = l1[i]

エッジ ケースの動作、場合の対処方法などを決定する必要がありますm<n

于 2012-10-20T19:42:54.220 に答える
1

これが私が面白いと思う簡潔な代替案です:

def stretch(seq, n):
    seq = [seq[i * (len(seq) - 1) // (n - 1)] for i in range(n)]
    return [seq[0]] + [x if x != y else None for x, y in zip(seq[1:], seq)]

そしてそれに基づいて、リストのコピーを作成しないitertoolsベースのバージョンは、オプションでリストに変換できるイテレータを返します。

from itertools import tee, chain, izip
def stretch(seq, n):
    s1, s2 = tee(seq[i * (len(seq) - 1) // (n - 1)] for i in range(n))
    return chain((next(s1),), (x if x != y else None for x, y in izip(s1, s2)))
于 2012-10-21T00:07:08.920 に答える