元组 vs 字符串 vs frozenset。不可变对象和内存中的副本数
Tuple vs String vs frozenset. Immutable objects and the number of copies in memory
a = "haha"
b = "haha"
print a is b # this is True
以上代码打印为真。我读过其中一个原因是因为字符串是不可变的,所以内存中的一个副本就足够了。但是在元组的情况下:
a = (1, 2, 3)
b = (1, 2, 3)
print a is b # this is False
尽管元组在 python 中也是不可变的,但这将打印 False。在做了更多研究之后,我发现元组可以包含可变元素,所以我想如果确定一个元组是否包含可变对象的成本太高,那么在内存中保存多个元组副本是有意义的。但是当我在 frozenset
上尝试时
a = frozenset([1,2])
b = frozenset([1,2])
print a is b # False
这也将打印错误。据我所知,frozenset 本身是不可变的,只能包含不可变对象(我试图创建一个 frozenset,其中包含一个包含可变列表的元组,但这是不允许的),我们可以使用 == 来检查两个 frozensets 是否是值相同,那么为什么 python 在内存中创建它们的两个副本?
这是因为 python byteops 的编译方式。当你的程序第一次运行时,它把代码编译成字节操作。当它执行此操作并在代码中看到字符串(或某些整数)文字时,它将创建一个字符串对象并在您键入该文字的任何地方使用对该字符串对象的引用。但在元组的情况下,很难(在某些情况下不可能)确定元组是否相同,因此执行此优化不需要额外的时间。正是出于这个原因,您通常不应使用 is
来比较对象。
你的句子"I've read that one of the reasons for this is because strings are immutable, so one copy in memory will be enough."是正确的,但并非总是如此。
例如,如果你对字符串做同样的事情
"dgjudfigur89tyur9egjr9ivr89egre8frejf9reimfkldsmgoifsgjurt89igjkmrt0ivmkrt8g,rt89gjtrt"
它不会是同一个对象(至少在我 python 的版本中)。
同样的现象可以在整数中复制,其中 256 将是同一个对象,但 257 则不是。
它与 python 缓存对象的方式有关,它保存 "simple" 对象。每个对象都有它的标准,对于字符串它只包含某些字符,对于整数它们的范围。
a = "haha"
b = "haha"
print a is b # this is True
以上代码打印为真。我读过其中一个原因是因为字符串是不可变的,所以内存中的一个副本就足够了。但是在元组的情况下:
a = (1, 2, 3)
b = (1, 2, 3)
print a is b # this is False
尽管元组在 python 中也是不可变的,但这将打印 False。在做了更多研究之后,我发现元组可以包含可变元素,所以我想如果确定一个元组是否包含可变对象的成本太高,那么在内存中保存多个元组副本是有意义的。但是当我在 frozenset
上尝试时a = frozenset([1,2])
b = frozenset([1,2])
print a is b # False
这也将打印错误。据我所知,frozenset 本身是不可变的,只能包含不可变对象(我试图创建一个 frozenset,其中包含一个包含可变列表的元组,但这是不允许的),我们可以使用 == 来检查两个 frozensets 是否是值相同,那么为什么 python 在内存中创建它们的两个副本?
这是因为 python byteops 的编译方式。当你的程序第一次运行时,它把代码编译成字节操作。当它执行此操作并在代码中看到字符串(或某些整数)文字时,它将创建一个字符串对象并在您键入该文字的任何地方使用对该字符串对象的引用。但在元组的情况下,很难(在某些情况下不可能)确定元组是否相同,因此执行此优化不需要额外的时间。正是出于这个原因,您通常不应使用 is
来比较对象。
你的句子"I've read that one of the reasons for this is because strings are immutable, so one copy in memory will be enough."是正确的,但并非总是如此。 例如,如果你对字符串做同样的事情 "dgjudfigur89tyur9egjr9ivr89egre8frejf9reimfkldsmgoifsgjurt89igjkmrt0ivmkrt8g,rt89gjtrt" 它不会是同一个对象(至少在我 python 的版本中)。 同样的现象可以在整数中复制,其中 256 将是同一个对象,但 257 则不是。 它与 python 缓存对象的方式有关,它保存 "simple" 对象。每个对象都有它的标准,对于字符串它只包含某些字符,对于整数它们的范围。