Как сделать Python для того, чтобы все одинаковые строки использовали одну и ту же память?
Возможный дубликат:
Что делает python intern и когда он должен использоваться?
Я работаю с программой в python, которая должна коррелировать по массиву с миллионами строковых объектов. Я обнаружил, что если все они взяты из одной строки, каждая дополнительная "строка" является просто ссылкой на первую, основную строку. Однако, если строки считываются из файла, и если все строки равны, для каждого из них все еще требуется новое распределение памяти.
То есть, это занимает около 14 месяцев хранения:
a = ["foo" for a in range(0,1000000)]
Хотя для этого требуется более 65 миллионов хранения:
a = ["foo".replace("o","1") for a in range(0,1000000)]
Теперь я могу сделать память с меньшим объемом с этим:
s = {"f11":"f11"}
a = [s["foo".replace("o","1")] for a in range(0,1000000)]
Но это кажется глупым. Есть ли более простой способ сделать это?
Ответы
Ответ 1
просто выполните intern()
, который сообщает Python хранить и извлекать строку из памяти:
a = [intern("foo".replace("o","1")) for a in range(0,1000000)]
Это также приводит к 18 МБ, как и в первом примере.
Также обратите внимание на комментарий ниже, если вы используете python3. спасибо @Abe Karplus
Ответ 2
вы можете попробовать что-то вроде этого:
strs=["this is string1","this is string2","this is string1","this is string2",
"this is string3","this is string4","this is string5","this is string1",
"this is string5"]
new_strs=[]
for x in strs:
if x in new_strs:
new_strs.append(new_strs[new_strs.index(x)]) #find the index of the string
#and instead of appending the
#string itself, append it reference.
else:
new_strs.append(x)
print [id(y) for y in new_strs]
которые идентичны, теперь будут иметь одинаковые id()
выход:
[18632400, 18632160, 18632400, 18632160, 18651400, 18651440, 18651360, 18632400, 18651360]
Ответ 3
Сохранение словаря видимых строк должно работать
new_strs = []
str_record = {}
for x in strs:
if x not in str_record:
str_record[x] = x
new_strs.append(str_record[x])
(тестировалась.)