Ограничить размер набора понимания из входа - PullRequest
0 голосов
/ 01 мая 2019

Есть ли способ ограничить размер заданного понимания при разборе ввода.Вот простой пример:

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 Ответ

2 голосов
/ 01 мая 2019

Вы не можете получить доступ к набору, так как он создается в понимании. Но вы можете связать вход, используя 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()}

Как я уже сказал, вы не можете получить доступ к набору, так как он создается в понимании, но это не мешает вам использовать другой набор. Но это делает бессмысленный дополнительный шаг копирования набора.

...