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

有时只需要一个简单的生成器:

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 回答
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]

在 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]

感谢@mgilson 的迭代反馈。

于 2013-02-02T18:40:54.380 回答