作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我必须定义一个函数,它接受一个可迭代对象并生成除最后 5 个值之外的所有值。截至目前,我有这样的东西:
def generate_all_but_5(iterable):
x = iter(iterable)
list_of_current = []
try:
while True:
list_of_current.append(next(x))
except StopIteration:
pass
for y in list_of_current[:-5]:
yield y
这是可行的,但是我不允许将可迭代的所有值复制到列表中,就像我在这里所做的那样,因为可能有无限数量的值。是否有另一种方法可以实现解决方案,而无需先将所有内容添加到列表中?
最佳答案
我认为在内存中只保存 5 个项目就可以了。你可以试试这个:
def generate_all_but_5(iterable):
x = iter(iterable)
list_of_current = []
for i, item in enumerate(x):
list_of_current.append(item)
if i >= 5:
yield list_of_current.pop(0)
它首先从可迭代对象中加载 5 个项目,然后弹出并生成列表的前面并附加下一个。最后五个仍将位于 list_of_current
中,并且不会产生 yield 。
list(generate_all_but_5(range(6)))
# [0]
list(generate_all_but_5(range(10)))
# [0, 1, 2, 3, 4]
list(generate_all_but_5('Hello world!'))
# ['H', 'e', 'l', 'l', 'o', ' ', 'w']
请注意,这样做的副作用是,虽然最后 5 个不会从 generate_all_but_5
返回,但它们仍然会从传入的可迭代中弹出。因为您没有提到保持可迭代中的最后 5 个不变,我认为没有这样的要求。
说明:
让我们在 for 循环中打印 list_of_current
来看看发生了什么。
def generate_all_but_5(iterable):
x = iter(iterable)
list_of_current = []
for i, item in enumerate(x):
print(list_of_current) # print the list
list_of_current.append(item)
if i >= 5:
yield list_of_current.pop(0)
g = generate_all_but_5(range(8))
n = next(g)
# []
# [0]
# [0, 1]
# [0, 1, 2]
# [0, 1, 2, 3]
# [0, 1, 2, 3, 4]
# n = 0
n = next(g)
# [1, 2, 3, 4, 5]
# n = 1
n = next(g)
# [2, 3, 4, 5, 6]
# n = 2
n = next(g)
# StopIteration Error
最后一次 yield 之后,list_of_current == [3, 4, 5, 6, 7]
。最后 5 个项目都在列表中,并且可迭代对象中没有剩余项目。
我不擅长解释事情。我希望这个例子有帮助!
关于python - 如何生成可迭代对象除了最后几个之外的所有值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53112352/
我是一名优秀的程序员,十分优秀!