2014-09-26 80 views
1

我列出列表中的元素相同。刪除一個

list = [[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]] 

我想要做的就是刪除一個相同值的元素應該我把第一個元素與第二的列表。例如[-2.0, 5.0] = -2/5[2.0, -5.0] = -2/5。我想刪除[-2.0, 5.0][2.0, -5.0],因爲它們產生相同的值。

任何想法?

+0

爲什麼這些所有'浮動'如果它們的值全部四捨五入到最接近的整數? – 2014-09-26 04:09:27

+0

'list'是一個關鍵字。使用別的東西。 – ssm 2014-09-26 04:13:33

回答

0

假設所有值都花車(所以你可以隨時使用float師),你可以做到以下幾點:

my_list = [[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]] 
values_seen = [] 
new_list = [] 

for x,y in my_list: 
    if x/y in values_seen: 
     continue 
    else: 
     values_seen.append(x/y) 
     new_list.append([x,y]) 

現在,你想要的名單將被存儲爲new_list。請注意,您應該避免像上面那樣爲關鍵字list寫入值。 *澄清,我假設如果您有超過2個返回相同比率的值(例如[[1,3],[2,6],[3,9]]),您將只想保留其中的一個。

0

如果你想消除所有等價分數(意思是[-2.0,5.0]和[4.0,-10.0]被認爲是等價的),那麼下面的代碼就可以工作。

seen = set() 
for numerator, denominator in lst: 
    quotient = numerator/denominator 
    if quotient not in seen: 
     seen.add(quotient) 
     yield numerator, denominator 

否則,如果你想最終名單同時包含[-2.0,5.0]和[4.0,-10.0]:

seen = set() 
for numerator, denominator in lst: 
    value = (abs(numerator), abs(denominator), sign(numerator)*sign(denominator)) 
    if value not in seen: 
     seen.add(value) 
     yield numerator, denominator 

如果你用Python寫這個,語言缺少sign函數,則需要使用math.copysign(numerator > 0)^(denominator > 0),其中^是xor運算符。

此代碼假設分子和分母都不爲零。

如果您確實在保留分子分母數對的列表,請考慮將這些對存儲爲不可變元組或更好,如Python fractions

0

快速和骯髒的方式,因爲字典中的鍵是唯一的。

{num/denom : [num, denom] for (num, denom) in lst}.values() 

通常,使用==比較浮點數是不可靠的,通常最好檢查它們是否在容差範圍內。例如

abs(x-y) < tolerance 

更穩健的方式可能看起來像下面這樣。另一個附加到for循環只是意味着要做到這一點,除非你提前退出循環。這非常方便。然而,這個版本是二次的,而不是線性的。

div = lambda x,y : x/y 

unique = [] 
for j in range(len(lst)): 
    for i in range(j): 
     if abs(div(*lst[i])-div(*lst[j])) < tolerance: 
      break 
    else 
     unique.append(lst[j]) 

unique 
+0

'__hash__'和'__eq__'在浮點數上都有精度問題,所以使用散列表並不能解決問題。例如,如果散列(-1/3.0)!=散列(1/-3.0),則散列表中將有兩個條目。 – IceArdor 2014-09-26 04:20:16

+0

謝謝,我的回答根本不清楚。我不是故意聲稱字典版本能夠解決寬容問題,我的意思是說它簡單快捷,並且會刪除重複內容。對於至少可以哈希的內建類型,如果兩個東西比較相等,那麼'__hash__'將爲這兩個返回相同的值。 – 2014-09-26 04:46:42

+0

可能需要重新排列您的解決方案爲「快速和骯髒的字典」,然後「考慮寬容」。所有必要的內容都在那裏,乍看起來令人困惑。 – IceArdor 2014-09-26 04:52:30

1

我可以嘗試這樣的:

元組可能是一本字典的關鍵,所以我轉換列表轉換成元組改爲腹肌列表元素的 價值,並保持原有的列表作爲值之後。

>>> lis 
[[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]] 
>>> dict([(tuple([abs(x[0]), abs(x[1])]), x) for x in lis]).values() 
[[2.0, -5.0], [1.0, 3.0]] 
>>> 
+1

我比我的解決方案更喜歡這個! +1 – ssm 2014-09-26 04:24:23

0

我會使用set首先得到了一套獨特的比率:

In [1]: lst = [[-2.0, 5.0], [-1.0, -3.0], [1.0, 3.0], [2.0, -5.0]] 

In [2]: rs = list(set([ l[0]/l[1] for l in lst])) 

然後就是篩選出比第一次出現:

In [3]: [ filter(lambda m: m[0]/m[1] == r , lst )[0] for r in rs ] 
Out[3]: [[-2.0, 5.0], [-1.0, -3.0]] 

In [4]: