Как сделать 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])

(тестировалась.)