知道这很可能以失败告终,我想知道Python将如何处理这种情况,以及我的代码是否实际上“有意义”,至少在原则上是这样。 所以这是我的尝试,我是python的新手(几天前),所以我确信我的代码对于有更多经验的人来说似乎很有趣,但是请耐心等待。
def make_inf_lst(lst):
lst = [0]
while 1 == 1:
for i in range(0, len(lst)):
add = lst[i] + 1
lst.append(add)
print(make_inf_lst([]))
这是我在DOS窗口中尝试运行上面的错误:
Traceback (most recent call last):
File "break_python.py", line 7, in <module>
print(make_inf_lst([]))
File "break_python.py", line 6, in make_inf_lst
lst.append(add)
MemoryError
谢谢。
答案 0 :(得分:6)
具有“无限”数据结构的语言实际上正在生成对象,这些对象会延迟或“按需”生成其值。他们创建一个对象,而不是先创建整个列表,当要求输入值时,可以在那个时候创建它。
在Python中,最容易使用生成器进行管理。
def make_inf_sequence():
x = 0
while True:
yield x
x = x + 1
# This returns immediately
naturals = make_inf_sequence()
# This loop runs forever
for i in naturals:
print(i)
答案 1 :(得分:2)
基本上有两件事可以阻止无限列表的打印(这似乎是代码的最终目标):
如果您想象一台虚拟的计算机,它具有无限的内存和无限的计算速度,则可以打印列表。
但是,某些语言通过“惰性”来支持无限列表,这意味着它们将只计算在特定点上所需列表的一部分。然后您可以定义一个无限列表并要求其打印出例如其中的前100个值。
有关延迟计算的更多信息: https://en.m.wikipedia.org/wiki/Lazy_evaluation
答案 2 :(得分:1)
从立即获得访问宇宙中所有成员的意义上讲,它不能是无限的。那将是不可能的-无限长度意味着需要无限的内存。从错误中您可以看到,您没有无限的内存。如其他人所述,您可以用速度来换长度:
select sum(cnt)
from (select value1, count(*) as cnt
from a
group by value1
having sum(value2 = 0) > 0
) a;
如果需要的话,在这里我将常规列表与动态扩展结合在一起。我不必从一个空列表开始,如果我愿意的话,我可以预先制作出前N个元素。
您当然可以重载运算符(+,-等等)。关键是一切都是一口气完成的。通过这种方式,您甚至可以添加和减去无限列表。
您甚至可以使用内存管理来改进此功能,并且如果一段时间内没有查看,则可以删除列表的开头,但是我认为这超出了范围。更具功能性的方法是保留当前数字和继续方式(我添加了from copy import deepcopy
class infinite_ints:
def __init__(self):
self.list = []
self.trans = lambda x: x;
def __getitem__(self,at):
try:
return self.trans(self.list[at])
except IndexError:
self.list += [i for i in range(len(self.list),at+1)]
return self.trans(self.list[at])
def apply(self,function):
new_list = deepcopy(self)
new_list.trans = lambda x,f=function,p=self.trans: f(p(x))
return new_list
>>> x[2]
2
>>> x[12]
12
>>> x[43]
43
>>> y = x.apply(lambda x: x+1)
>>> y[59]
60
类似于内置的prev
:
__next__
同样,可以很容易地实现运算符(而不仅仅是表示形式)或跳转多个。
答案 3 :(得分:1)
构建列表时,您的计算机有时会耗尽内存,这就是导致您看到错误的原因。不可能有无限列表,因为内存是有限的资源。
或者,您可以使用无限迭代器。标准库提供了一些无限迭代器。根据您的示例,我认为最适合您的情况的是itertools.count
。
样品用量:
>>> from itertools import count
>>> it = count()
>>> next(it)
0
>>> next(it)
1
您还可以指定自定义起点:
>>> from itertools import count
>>> it = count(5)
>>> next(it)
5
>>> next(it)
6
还有一个自定义步骤:
>>> from itertools import count
>>> it = count(5, 2)
>>> next(it)
5
>>> next(it)
7
>>> next(it)
9
答案 4 :(得分:0)
无限数据结构确实很有意义,但是必须总是进行延迟评估。这意味着您的数据结构不能立即构建其所有元素,然后再四处移动(就像我们通常使用适合内存的list
一样)。相反,您的数据结构需要根据需要提供值。
在Python中,不能有无限的list
,因为list
渴望而不是懒惰(就像Python中的大多数事情一样,渴望是默认的)。清楚一点,我在这里谈论的是list
类型。 Python术语,而不是某些序列的抽象概念(某些人可能称其为列表)。
您可以通过使用名为generator
的方法来进行延迟评估。如果要生成序列1,2,3,4,...
,则可以使用以下代码进行生成:
def gen_natural_numbers():
cur = 1
while True:
yield cur
cur += 1
natural_num_gen = gen_natural_numbers()
print("One: ", next(natural_num_gen))
print("Two: ", next(natural_num_gen))
print("Three: ", next(natural_num_gen))
此输出:
One: 1
Two: 2
Three: 3
很显然,您不必在3处停止。您不必在任何地方停止(除非您创建的int
实际上不适合内存)。如果您继续调用next
,则生成器将继续向您返回值。
在进行过程中,垃圾收集器可以从不再包含引用的内存中删除值。这完全是另一个主题,但是应该注意的是,只要您不永远保留引用,那么使用生成器时,程序也不会耗尽内存。