Python中的字符串是不可变的,这意味着该值不能更改。我正在测试该场景,但看起来原始字符串已被修改。
>>> s = 'String'
>>> for i in range(5, 0, -1):
... s += str(i)
... print(f"{s:<11} stored at {id(s)}")
...
String5 stored at 139841228476848
String54 stored at 139841228476848
String543 stored at 139841228476848
String5432 stored at 139841228476848
String54321 stored at 139841228476848
>>> a = "hello"
>>> id(a)
139841228475760
>>> a = "b" + a[1:]
>>> print(a)
bello
>>> id(a)
139841228475312
当所附加的str恰好没有其他活引用时,这是一个特定于CPython的优化。在这种情况下,解释器“作弊”,允许它通过重新分配(根据堆布局,可以在适当的位置)和直接附加数据来修改现有字符串,而且经常会显著减少重复串联的循环中的工作量(使其更像是列表的摊销附件,而不是每次复制操作)。除了未更改的id之外,它没有任何可见的效果,因此这样做是合法的(除非逻辑上替换了str,否则任何人都不会看到它的更改)。
根据PEP8的第一个编程建议,您实际上不应该依赖它(非引用计数的解释器不能使用这个技巧,因为他们不知道str
是否有其他引用):
代码的编写方式应不影响其他Python实现(PyPy、Jython、IronPython、Cython、Psyco等)。
例如,不要依赖CPython对形式为a=b
或a=ab
的语句的就地字符串串联的高效实现。这种html" target="_blank">优化即使在CPython中也很脆弱(它只适用于某些类型),并且在不使用refcounting的实现中根本不存在。在库中对性能敏感的部分中。应改用join()表单。这将确保在各种实现中以线性时间进行连接。
如果您想打破优化,有各种方法可以做到这一点,例如将代码更改为:
>>> while i!=0:
... s_alias = s # Gonna save off an alias here
... s += str(i)
... print(s + " stored at " + str(id(s)))
... i -= 1
...
通过创建别名、增加引用计数并告诉Python更改将在s
以外的其他地方可见,因此它无法应用它来打破它。类似的代码:
s = s + a + b
不能使用它,因为s a
首先出现,并产生一个临时的b
然后必须添加到其中,而不是立即替换s
,并且优化太脆弱而无法尝试处理它。几乎相同的代码如下:
s += a + b
或:
s = s + (a + b)
通过确保最终串联始终为左操作数,并使用结果立即替换左操作数来恢复优化。
Python中的字符串是不可变的,这意味着该值不能更改。但是,在以下示例中,当附加到字符串时,由于id保持不变,看起来原始字符串内存被修改了: 相反,在以下示例中,id更改:
这个问题更容易用代码内联解释: 我已经被困在这个舞台问题上好几天了。我似乎也找不到工作。有我看不到的差异吗?两个相等的字符串怎么会表现得如此不同呢。请帮帮我,我要发疯了,想办法解决这个问题! 我得到的具体例外是: 原因:java.io.NotSerializableException:org.apache.hadoop.hdfs.分布式文件系统序列化堆栈:-对象不可序列化(类:org.apache
根据逻辑,我需要实现两个,如果它们以相同的“相对”顺序具有相同的元素,则它们被认为是相等的。 举个例子,以下一对列表被认为彼此相等: 只要遵守相对顺序,就可以认为它们是平等的。 作为反例,这两个不相等: 导致 和 交换到位。 所以,基本上我发现这很有挑战性,因为这不是顺序完全重要的情况,也不是顺序完全不重要的情况。在这种情况下,我会使用普通的< code>list1.equals(list2)方法
问题内容: 这样的情况有效吗? 问题答案: 没有。 元素ID在整个文档中应该是唯一的。
我得到以下错误: 它可能是另一种类型,而不是,但基本上模式是 所以 什么是未来 如何获得我想要的实际值 当我只有一个
我的程序向用户询问测试分数并显示最小/最大值、测试#和平均值。但是,如果分数不在0到10之间,我不希望在计算中使用该数字。我将如何在do/time循环中执行此操作?我尝试过输入System.exit(0);在if(num }