我有一个大的序列相关的问题要解决以下是子问题,我确信它在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
我可以通过编写一个小函数轻松解决上述问题,但我在变量定义时需要它。
答案 0 :(得分: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()
。
答案 1 :(得分: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 as iter,
>>> 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提供的反馈意见。
答案 2 :(得分: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
答案 3 :(得分: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
。