Вы не можете получить доступ к набору, так как он создается в понимании. Но вы можете связать вход, используя itertools.islice()
.
import sys
from itertools import islice
values = {x.strip() for x in islice(open(sys.argv[1], 'r'), 100)}
Это ограничивает размер, но так как наборы не допускают дублирования, результирующий набор может быть меньше 100, даже если в отличие от вашего цикла for существует более 100 значений, которые останавливаются при размере набора ровно 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()}
Как я уже сказал, вы не можете получить доступ к набору, так как он создается в понимании, но это не мешает вам использовать другой набор. Но это делает бессмысленный дополнительный шаг копирования набора.