我有一个整数列表和一个元组列表(表示间隔),我想编写一个方法,对于每个元组,返回包含在区间中的整数的子列表,但是我想用生成器来实现它。
用于下列投入:
l = [1, 2, 3, 4, 5]
intervals = [(1, 2), (2, 4)]子列表应该是:[1, 2]和[2, 3, 4]。
我的尝试:
def gen_intervals(l, intervals):
for e in l:
for i in intervals:
if e > i[0] and e < i[1]:
yield e但是,这将给我一个元素列表,因为生成器一次生成一个元素。我想要的是在这个区间内产生一个元素的生成器。
然后,我会像这样用它:
for interval in gen_intervals(l, intervals):
for e in interval:
print(e)重要信息:
发布于 2022-08-22 09:29:54
您可以简单地在yield行上使用生成器理解:
def gen_intervals(elements, intervals):
for vmin, vmax in intervals:
yield (elm for elm in elements if (vmin <= elm <= vmax))这意味着:
l = [1, 2, 3, 4, 5]
intervals = [(2, 4), (1, 2)]
for interval in gen_intervals(l, intervals):
for e in interval:
print(e)
print()2
3
4
1
2发布于 2022-08-22 08:54:17
你可以这样做。每个间隔生成器都有一个缓冲区,当请求项时,它首先刷新缓冲区,然后选择下一个list元素。如果该元素恰好是“它的”元素,则生成它,否则将其放置在相应区间的缓冲区中,然后尝试使用下一个元素。
def items_by_iterval(lst, intervals):
list_iter = iter(lst)
buffers = [[] for _ in intervals]
def interval_iter(n):
while True:
if buffers[n]:
yield from buffers[n]
buffers[n] = []
try:
k = next(list_iter)
except StopIteration:
return
for m, (a, b) in enumerate(intervals):
if a <= k <= b:
if m == n:
yield k
else:
buffers[m].append(k)
break
return [interval_iter(n) for n, _ in enumerate(intervals)]
##
lst = [1, 9, 2, 8, 3, 7, 4, 6, 5, 1, 9, 2, 8, 3, 7, 4, 6, 5, ]
intervals = [(5, 7), (2, 4), (8, 10)]
for ii in items_by_iterval(lst, intervals):
for k in ii:
print(k, end=' ')
print()这些指纹:
7 6 5 7 6 5
2 3 4 2 3 4
9 8 9 8发布于 2022-08-22 09:01:20
与任何for循环不同,您可以使用map为每个间隔的每个元素创建一个具有True和False值的列表。然后,您可以使用itertools.compress创建一个迭代器对象,该对象生成在各自间隔内的元素:
import itertools
l = [1, 2, 3, 4, 5]
intervals = [(2, 4),]
for interval in intervals:
# use range(i+1, j) to check if element is in interval
mapped = map(lambda el: el in range(interval[0] + 1, interval[1]), l)
# mapped = [False, False, True, False, False]
res = itertools.compress(l, mapped) # save this in case of more intervals
print(next(res)) # returns 3https://stackoverflow.com/questions/73441900
复制相似问题