Экономия памяти Cheapo доступна, потому что вы используете Python 3.6+: используйте dict
, а не set
.Несмотря на необходимость хранить значение для каждого элемента, dict
s часто использовали немного меньше памяти даже в старых версиях Python (они оптимизированы для разных целей; set
имеет тенденцию перераспределять сегменты, чтобы уменьшить риск столкновений блоков,но это стоит больше памяти);в версии 3.6+ они перешли к более компактному dict
дизайну, который экономит еще больше, пока уникальные данные не велики (set
s может начать выигрывать снова для некоторых размеров, когда количество уникальных предметов превышает 2**15
/ 32768, так как прирост компактности резко падает в этой точке).
Чтобы изменить его, просто сделайте:
a = {}
x = int(input())
for _ in range(x):
a[input()] = None
print(len(a))
Кроме того, для скорости, если вам не нужноиспользуйте input
, вам, вероятно, следует избегать этого и просто читать из sys.stdin
напрямую;input
выполняет много ненужной очистки выходов и другой работы, которая вам здесь не нужна.Так что, скорее всего, это будет еще быстрее:
import itertools, sys
x = int(input())
a = dict.fromkeys(itertools.islice(sys.stdin.buffer, x))
print(len(a))
, который просто тянет линии без изменений и толкает их прямо в dict
на уровне C для дополнительной скорости.Измените sys.stdin
на sys.stdin.buffer
, чтобы вообще не расшифровывать строки, и добавьте map(str.rstrip, ...)
или map(bytes.rstrip, ...)
для sys.stdin.buffer
, чтобы удалить новые строки (если последняя строка может не заканчиваться новой строкой, это необходимо для правильностии, я полагаю, это экономит тривиальный объем памяти).
Если входные данные могут быть огромными (более пятизначные уникальные входные данные), то dict
, скорее всего, не поможет, поэтому просто придерживайтесь set
, но вы все равно можете использовать sys.stdin
оптимизации, что приведет к окончательной форме, такой как:
x = int(input())
a = set(itertools.islice(map(bytes.rstrip, sys.stdin.buffer), x))
print(len(a))