[英]How can I run the Python3 interpreter with variables/references/etc as defined in a python file?
[英]Python3: How can I control behavior of user defined class?
有這樣的排序功能:
def iterative_insertion_sort(A):
'''Sort A iteratively.'''
for i, key in enumerate(A[1:]):
while i > -1 and A[i] > key:
print(id(key), id(A[i+1]))
A[i + 1] = A[i]
print(id(key), id(A[i+1]))
i = i - 1
A[i + 1] = key
排序功能在浮點數方面效果很好。
樣本輸出:./insertion_sort.py .23 .21 .26
140566861513304 140566861513304
140566861513304 140566861513256
[0.21, 0.23, 0.26]
但是我有一個名為lList的自定義類,它具有鏈接(另一個自定義類)類型的元素。 當我輸入lList的實例時,排序無法正常進行。
樣本輸出:0.23 0.21 0.26 /
139732300992808 139732300992808
139732300992808 139732300992808
0.23 0.23 0.26 /
如我們所見,在使用float的情況下,賦值語句之后key和array元素的id不同。 但是對於自定義類,即使在分配操作之后,鍵和數組元素的ID也相同。 這是麻煩的原因。
我懷疑問題是因為浮點數是不可變的,而我的自定義類不是。 我的問題是解決情況的最佳方法是什么?
注意:在排序過程中,我希望零到最小變化。 但是,我願意自定義我的lList或鏈接類。
PS我剛剛只發布了相關的代碼段。 如果還需要類定義,只需提及它,我也會添加它。
非常感謝!
更新:
鏈接定義:
class link:
'''Implement link.'''
def __init__(self, key=None):
self.key = key
self.nxt = None
self.prev = None
def __str__(self):
'''Print link.'''
if self:
return str(self.key)
else:
return '/'
def __gt__(self, other):
return self.key > other.key
這是lList定義:
class lList:
'''Implement list of links.'''
def __init__(self):
self._head = None
self._numberOfLinks = 0
def list_insert(self, x):
'''Insert link x at the beginning of list.'''
x.nxt = self._head
if self._head:
self._head.prev = x
self._head = x
self._numberOfLinks += 1
def __str__(self):
'''Print list of links.'''
listFormat = ''
temp = self._head
while temp:
listFormat += str(temp) + ' '
temp = temp.nxt
else:
listFormat += '/ '
return listFormat
def get_data(self, position):
'''Return link from list at position position from head.'''
i = 0
temp = self._head
while i < position:
temp = temp.nxt
i += 1
return temp
def set_data(self, position, newLink):
'''Overwrite key of link at position distance from head of list with key of newLink.'''
i = 0
temp = self._head
while i < position:
temp = temp.nxt
i += 1
temp.key = newLink.key
def __getitem__(self, position):
if type(position) is slice:
return [self[i] for i in range(*position.indices(len(self)))]
elif type(position) is int:
if position < 0:
position += len(self)
if position >= len(self):
raise IndexError("The index (%d) is out of range."%position)
return self.get_data(position)
else:
raise TypeError("Invalid argument type.")
def __setitem__(self, position, value):
self.set_data(position, value)
def __len__(self):
return self._numberOfLinks
這是創建相同場景的最少代碼:
test = lList()
l = link(.26)
test.list_insert(l)
l = link(.21)
test.list_insert(l)
l = link(.23)
test.list_insert(l)
print(test)
iterative_insertion_sort(test)
print(test)
是的,問題不只是不變性之一,而更多是共享參考。
在對浮點值進行排序時,將對存儲在A[1]
中的浮點數的引用存儲在key
。 然后,使用A[0]
的值更改A[1]
的引用。 這意味着A[1]
現在指向另一個對象,稍后將A[0]
設置為key
就可以了。
但是,在對鏈表進行排序時,您永遠不會更改A[1]
。 您更改A[1]
的屬性 。 key
和A[1]
繼續指向同一link
實例,並且在key.key
也可以看到設置A[1].key
。
您可以通過將整個link
對象實際替換為新的link
對象來解決此問題:
def set_data(self, position, newLink):
'''Overwrite key of link at position distance from head of list with key of newLink.'''
i = 0
temp = self._head
while i < position:
temp = temp.nxt
i += 1
newlink = link(newLink.key)
if temp.prev:
temp.prev.nxt = newlink
else:
self._head = newlink
newlink.nxt = temp.nxt
這等同於在Python list
對象中設置新值:
(4302695168, 4302695168)
(4302695168, 4303149248)
0.21 0.23 0.26 /
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.