Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python—如何区分指向同一对象的两个列表元素?_Python - Fatal编程技术网

Python—如何区分指向同一对象的两个列表元素?

Python—如何区分指向同一对象的两个列表元素?,python,Python,我有一个如下实现的环形结构(基于我找到的食谱): 假设我这样做: x = Ring([1,2,3,4,4]) x.setTop(4) 我的代码将始终将前4个(当前为x[3])设置为x[0]。看起来(通过x[3]和x[4]之间的对象标识和散列id测试),Python正在重用4对象 我如何告诉Python我真的希望第二个4(目前是x[4])位于顶部 为基本问题道歉。。。作为一个自学成才的初学者的失败之一 谢谢 迈克 ==编辑=== 无论如何,我从类中删除了setTop方法。我将它添加到标准配方中,

我有一个如下实现的环形结构(基于我找到的食谱):

假设我这样做:

x = Ring([1,2,3,4,4])
x.setTop(4)
我的代码将始终将前4个(当前为x[3])设置为x[0]。看起来(通过x[3]和x[4]之间的对象标识和散列id测试),Python正在重用4对象

我如何告诉Python我真的希望第二个4(目前是x[4])位于顶部

为基本问题道歉。。。作为一个自学成才的初学者的失败之一

谢谢

迈克

==编辑===

无论如何,我从类中删除了setTop方法。我将它添加到标准配方中,并认为“嘿,这会很简洁,可能很有用。”正如答案(特别是“区别是什么”,这一点非常正确)和我自己使用该结构的经验所表明的,这是一种蹩脚的方法,不支持我的任何用例


换言之,添加一些东西是因为我可以代替满足需求=失败。

我也不太清楚,但我猜数字,即使是being对象,在代码的不同点使用时也是相同的对象。 我为什么这么认为?看:

>>> type(2)
<type 'int'>
>>> type(lambda x:x)
<type 'function'>
>>> 2 is 2
True
>>> (lambda x: x) is (lambda x: x)
False
>类型(2)
>>>类型(λx:x)
>>>二等于二
真的
>>>(λx:x)是(λx:x)
假的

创建两次时,两个对象不相同。但数字不是你创造的,它们已经存在了。给一个
4
对象与另一个
4
对象不同是没有意义的。至少我没有看到一个。

如果你知道你想要第二个,那就去吧

x = Ring([1,2,3,4,4])
x.setTop(4)
x.turn()
x.setTop(4)

您可以增强setTop()以获取一个附加参数并在内部执行。

对于较小的数字,python将预先制作对象缓存,以避免制作新对象的成本。它们将具有相同的对象标识。Java也能做到这一点。您需要一种方法来避免这样做。

学习Python,第4版——第6章:

至少在概念上,每次通过运行 表达式,Python创建一个新对象(即内存块)来表示该对象 价值在内部,作为一种优化,Python缓存并重用某些类型的un- 可变对象,例如小整数和字符串(每个0实际上不是一个新的部分 有关此缓存行为的更多信息(稍后)。但是,从逻辑的角度来看,它 就像每个表达式的结果值是一个不同的对象,每个对象都是一个 独特的记忆片段

问题是

if x[3] is x[4]:
    print "What's the difference?"

Python重用小整数和短字符串。据我所知,这是没有办法的-你必须接受这一事实,
setTop
只在第一场比赛前旋转。我想您可以添加一个可选参数,
n=1
,然后旋转直到第
n
次匹配。但这有点离题了,不是吗

不相关的,考虑这个:

>>> class Point(object):
...     def __init__(self, x, y):
...         self.x, self.y = x, y
...     def __eq__(self, other):
...         return (self.x == other.x and self.y == other.y)
... 
>>> a_ring = Ring(Point(1, 2), Point(15, -9), Point(0, 0))
>>> a_ring.seTop(Point(15, -9))
Traceback ...
...
ValueError: object not in ring
不是它应该怎么工作的,是吗?当self[0]!=objectReference(顺便说一句,这是一个误导性的名称)来避免这种情况。

Cpython有一个用于小整数的“整数缓存”,因此从-5到255的值(可能因版本或Python实现而异)对给定值重用同一对象。也就是说,所有4都是相同的int对象,值为4。这样做是为了减少创建对象的必要性

有几种方法可以解决这个问题

  • 您可以使用长整数(例如,写入4L而不是4)。Python不对长整数使用缓存。(您也可以使用浮点数,因为它们同样不会被缓存。)但是,如果您对这些数字进行大量计算,这可能会导致一些性能损失
  • 您可以将每个项目包装在列表或元组中(因为有简单的语法,尽管它比长整数或浮点语法要多)
  • 您可以创建自己的对象来包装整数。对象将具有与整数相同的所有方法(因此它在数学、比较、打印等方面与整数类似),但每个实例都是唯一的

我个人喜欢在这种情况下使用长整数。在构造函数中,以及在任何添加项的方法中,您都可以轻松地将整数转换为长整数。

听起来您总是希望至少转换一次,对吗?如果是,请重新编写setTop方法,如下所示:

def setTop(self, objectReference):
    if objectReference not in self:
        raise ValueError, "object is not in ring"

    self.turn()
    while self[0] is not objectReference:
        self.turn()
然后在预期状态之间循环:

>>> x = Ring([1,2,3,4,4])
>>> x
[1, 2, 3, 4, 4]
>>> x.setTop(4)
>>> x
[4, 4, 1, 2, 3]
>>> x.setTop(4)
>>> x
[4, 1, 2, 3, 4]
>>> x.setTop(4)
>>> x
[4, 4, 1, 2, 3]

说得好。我不确定我是否希望它以这种方式工作。我得好好想想。我得说,四个月前我第一次开始学习python时,我在书店里买了一本学习python的书,当时我很匆忙。这完全是浪费时间。它之所以如此厚实,是因为它重复了所有广告中的内容,但仍然漏掉了一半要说的内容。简而言之,Python要好得多。关于这个主题,这里的区别是建模环的旋转状态。当然,但是如果环中有两个基本常数,那么基于这些文字之间关系的建模环的旋转状态是没有意义的。谁在乎它是抓住第一个常数还是第二个常数?因为它们具有相同的属性,所以没有真正的区别。如果有不同的对象,python的反射工具将显示它们之间的差异,从而允许在建模环中存在明显的差异。如果我给你一根两端都标有“4”的棍子,然后说“从4开始,到另一端”,你选哪一根4有关系吗?是的,有关系。假设是4-2-3-4。你是先穿过2还是3?想要说明它是什么的愿望一点也不不不合理。当然,但这并不是上面问题中提出的问题领域。此外,假设我们的MikeRand对您的环感兴趣,他必须指定位置逻辑(即:如果
>>> x = Ring([1,2,3,4,4])
>>> x
[1, 2, 3, 4, 4]
>>> x.setTop(4)
>>> x
[4, 4, 1, 2, 3]
>>> x.setTop(4)
>>> x
[4, 1, 2, 3, 4]
>>> x.setTop(4)
>>> x
[4, 4, 1, 2, 3]