限制来自输入的集合理解的大小

时间:2019-05-01 00:19:12

标签: python out-of-memory limit set-comprehension

在解析输入时是否有一种方法来限制设置理解的大小。这是一个简单的示例:

import sys

values = {x.strip() for x in open(sys.argv[1], 'r')}

print(values)

values的大小是不受限制的,但是有什么方法可以限制它?可以使用如下所示的for循环来完成此操作,但是有一种更简单的方法吗?

import sys

values = set()
for x in open(sys.argv[1], 'r'):
    values.add(x.strip())

    if len(values) > 100:
       break

print(values)

1 个答案:

答案 0 :(得分:2)

您无法访问该集,因为它是一种综合的构建方式。但是您可以使用itertools.islice()来限制输入。

import sys
from itertools import islice

values = {x.strip() for x in islice(open(sys.argv[1], 'r'), 100)}

这确实限制了大小,但是由于集合不允许重复,因此即使有100个以上的值,结果集也可能小于100,这与您的for循环不同,for循环会在恰好为101的集合大小处停止


  

那将限制输入值的数量,但是我想限制存储的唯一值的数量。

限制输入确实限制了输出的大小。但是,如果您希望用更少的行显示示例的确切行为,就可以了。

import sys

values = set()
any(values.add(x.strip()) and len(values) > 100 for x in open(sys.argv[1]))

print(values)

内置any()将从生成器表达式中提取出来,直到用尽它或找到一个真值,以先到者为准。表达式values.add(x.strip())将始终返回None,因此生成器仅在True时才返回len(values) > 100

虽然这确实将整个for循环压缩为一行,但可以说没有那么简单。然后的问题是,您觉得哪个更具可读性?


  

感谢其他示例。它实现了限制集合大小的最初目标,但是正如您所指出的,它实际上只是编写我最初发布的循环的另一种方法。我希望有一种方法可以在一定的理解范围内做到这一点,从而从中获得好处。

这些有什么好处?您当然可以可以全部理解,但是实际上没有意义。

{x for values in [set()]
 if any(values.add(x.strip())
        and len(values) > 100
        for x in open(sys.argv[1]))
    or True
 for x in values()}

就像我说的那样,您无法访问集合,因为它是一种综合的构建方式,但这并不能阻止您使用其他集合。但这确实是复制集合的毫无意义的额外步骤。