0

以下がサブ問題である解決すべき大きなシーケンス関連の問題があります。これは、私が認識していないPythonの非常に基本的なものであると確信しています。

seq = [4*x for x in range (1,(20/4))]
generates seq = [4, 8, 12, 16]

どうすれば生成できますか

[4, 4, 8, 8, 12, 12, 16]

seq = [4*x, 4*x for x in range (1,(20/4))] does not work

上記の問題は小さな関数を書くことで簡単に解決できますが、変数定義時に必要になります。

4

4 に答える 4

7

タプルのリストが生成されるため、ソリューションは機能しません。

あなたが探しているのは、作成したリストを平坦化する方法です。これを行う最も簡単な方法は次のitertools.chain.from_iterable()とおりです。

>>> list(itertools.chain.from_iterable([4*x]*2 for x in range(1, 5)))
[4, 4, 8, 8, 12, 12, 16, 16]

あなたの例のように、最後の値を一度だけ持つつもりなら、単にリストの最後をスライスしてください ( seq[:-1])。

注として、必要な繰り返しごとに値を繰り返すのではなく、リストを使用してそれを乗算することができます (値が不変であるか、同じオブジェクトであることを気にしない場合)。代替手段はitertools.repeat().

于 2013-02-02T18:32:13.230 に答える
0

別の方法:

>>> seq = [4, 8, 12, 16]
>>> seq = [i for s in zip(seq,seq) for i in s]
>>> seq
[4, 4, 8, 8, 12, 12, 16, 16]

iterとしてのseqの場合、

>>> seq = [4, 8, 12, 16]
>>> seq = [i for s in zip(seq,seq.copy()) for i in s]
>>> seq
[4, 4, 8, 8, 12, 12, 16, 16]

iterフィードバックをありがとう@mgilson。

于 2013-02-02T18:40:54.380 に答える
0

単純なジェネレーターで十分な場合もあります。

def doubler_almost(seq):
    """
    Yield elements from a sequence twice until the last element
    which is only yielded once
    """
    iseq = iter(seq)
    y = next(iseq)
    yield y
    for x in iseq:
        yield y
        yield x
        y = x

print list(doubler_almost(range(4,20,4)))

-- このジェネレーターは、より良い名前を付けることで間違いなく恩恵を受けることができますが...

他の回答から得られないこの回答から得られることは、最後の要素を切り捨てるためにリストに変換する必要がないことです。完全に遅延評価できます。また、ジェネレーターを渡すこともできますが、それでも機能します (ただし、Lattyware による回答はその場合でも機能しますが、最初zipに使用しない限り回答は機能しませんitertools.tee)。

于 2013-02-02T18:52:49.473 に答える
0

@shantanooの回答のバリエーション:

[ 4 * i for s in itertools.izip(*itertools.tee(range(1,5))) for i in s]

出力

[4, 4, 8, 8, 12, 12, 16, 16]

本当にそれはただの言い訳でしたitertools.tee:D

于 2013-02-02T18:48:03.663 に答える