我想創建一個同時包含整數和浮點數的集合。就像這樣:
s = {4, 6.7, 2.12, 9}。
然而,我遇到了一些意想不到的事情(至少對我來說)。我不能同時添加9(一個整數)和9.0(一個浮點數)。下面是一個例子:
>>> s = {4, 6. 7, 2.12, 9}.
>>> s
{9, 2.12, 4, 6.7}。
>>> s.add(9.0)
>>> s.
{9, 2.12, 4, 6.7}。
- 為什么會這樣?
- 我怎樣才能將這兩個數字添加到我的集合中?
我不希望9.0 in s成立,如果我沒有把浮動的數字添加到我的集合中。我真的想不出該怎么做。
另外,我注意到對于字典的鍵也是如此。所以我不能將3和3.0映射為不同的值。
uj5u.com熱心網友回復:
在Python中9.0 == 9和平等是集合中唯一性的基礎。
如果你想讓相等的float和int數字不在你的集合中碰撞,你實際上有兩個屬性用于比較:值,和型別。
最簡單的解決方案是簡單地將它們都存盤在集合中,使用一個tuple。比如說
s = set( )
s.add( (float, 1.0 ) )
s.add( (float, 5.0 ) )
s.add( (int, 5 )
s.add( (float, 5.0) )
簡單但有點尷尬,并且依賴于你設定正確的型別:沒有什么可以阻止你使用一個int值添加一個float。另外,你可以實作一個set子類,為你處理這個魔法
class TypedSet(set)。
def add(self, v)。
vtype = type(v)
super( ).add( (vtype, v) )
def remove(self, v)。
vtype = type(v)
super().remove( (vtype, v) )
s = TypedSet()
s.add(1.0)
s.add(5.0)
s.add(5)
s.add(5.0)
注意:對于一個真正的實作,這需要更多的作業。
上述內容將產生以下集合(注意,重復的5.0的行為是預期的)。
TypedSet({(<class 'float'/span>>, 1. 0), (<class 'int'>, 5), (< class 'float'>, 5. 0)})
所以這是可能的,但如果我是你,我會停下來檢查你是否真的想這樣做。如果你有兩件想要追蹤的事情,也許你想要的是兩組?
當你需要對它們進行迭代/處理時,你總是可以將這些集合合并為一個元組,例如:
。
my_floats = set()
my_ints = set()
my_floats.add(1.0)
my_floats.add(5.0)
my_ints.add(5)
my_floats.add(5.0)
combined = (*my_floats, *my_ints) # combined to a tuple[/span].
將給你以下的結果(沒有任何魔法)...
(1.0, 5.0, 5)
uj5u.com熱心網友回復:
set從根本上說是一個hashtable。為了處理碰撞,它檢查兩個具有相同哈希值的物件是否相等,如果相等,它只是假設它已經擁有的物件是正確的。或者類似的東西。
問題是,floats是整數,具有與整數相同的哈希代碼。順便說一下,任何足夠小的整數在python中的哈希值都等于該整數。
與其重新實作或子類化set,不如重新實作float類,使其哈希值與整數不同:
class hfloat(float)。
def __hash__(self):
if self == int(self)。
return hash((float, float.__hash__(self))
else:
return float.__hash__(self)
s = {4, 6.7, 2.12, 9}。
s.add(hfloat(9.0)
print(s)
# {2.12, 4, 6.7, 9, 9.0}
免責宣告:具有相同整數值的hfloat和float現在不會有相同的哈希值,所以這也可能發生:
s = {9.0, hfloat(9.0)}
print(s)
# {9.0, 9.0}
按照評論中的建議,在hashtable中存盤(value, type)2元組可能更適合你的用例。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/323167.html
標籤:
上一篇:TrayIcon位置的MouseListener不正確
下一篇:將JButton添加到畫布
