基于具有一组迭代步骤的列表迭代列表
我想根据存储在另一个列表中的可变迭代次数和作为整数存储的恒定跳过次数来迭代给定列表。
假设我有 3 件事 -
l- 我需要迭代(或过滤)的列表w- 一个列表,告诉我休息前要迭代多少项k- 一个整数,告诉我在每组迭代之间跳过多少个元素。
换个说法,w 告诉要进行多少次迭代,在每组迭代之后,k 告诉要跳过多少个元素。
所以,如果 w = [4,3,1] 并且 k = 2。然后在给定的列表(长度为 14)上,我想迭代前 4 个元素,然后跳过 2,然后是接下来的 3 个元素,然后跳过 2,然后下一个元素,然后跳过 2。
另一个例子,
#Lets say this is my original list
l = [6,2,2,5,2,5,1,7,9,4]
w = [2,2,1,1]
k = 1
基于 w 和 k,我想迭代为 -
6 -> Keep # w says keep 2 elements
2 -> Keep
2 -> Skip # k says skip 1
5 -> Keep # w says keep 2 elements
2 -> Keep
5 -> Skip # k says skip 1
1 -> Keep # w says keep 1 element
7 -> Skip # k says skip 1
9 -> Keep # w says keep 1 element
4 -> Skip # k says skip 1
我尝试从 itertools、numpy、嵌套循环的组合中找到一些东西,但我似乎无法理解如何甚至迭代这个。抱歉没有提供任何尝试,但我不知道从哪里开始。
我不一定需要完整的解决方案,只需一些提示/建议即可。
回答
这有效:
l = [6,2,2,5,2,5,1,7,9,4]
w = [2,2,1,1]
k = 1
def take(xs, runs, skip_size):
ixs = iter(xs)
for run_size in runs:
for _ in range(run_size ):
yield next(ixs)
for _ in range(skip_size):
next(ixs)
result = list(take(l, w, k))
print(result)
结果:
[6, 2, 5, 2, 1, 9]
该函数就是所谓的生成器,一次产生一部分结果,这就是为什么它被组合成一个列表 list(take(l, w, k)).
在函数内部,xs传入的列表被包装在一个迭代器中,以便能够使用next().
runs定义要获取和产生的项目数量,skip_size定义每次“运行”后要跳过的项目数量。
作为奖励,这是一个有趣的单行 - 如果你能弄清楚它为什么起作用,我认为你对这个问题有足够的了解可以继续:)
[y for i, y in zip([x for xs in [[1] * aw + [0] * k for aw in w] for x in xs], l) if i]