2012-10-28 107 views
1

我想搜索現有列表中的數字。如果其中一個數字重複,則將變量的值設置爲true並中斷循環。Python:比較更多數字

list = [3, 5, 3] //numbers in list 

所以,如果函數得到兩個相同的數字,然後打破 - 在這種情況下,有3重複。

如何做到這一點?

回答

2

你可以看看sets。您循環訪問您的列表,然後將該編號添加到支持集或打破循環。

>>> l = [3, 5, 3] 
>>> s = set() 
>>> s 
set([]) 
>>> for x in l: 
...  if x not in s: 
...   s.add(x) 
...  else: 
...   break 

你也可以採取一步,做一個函數出這個代碼,返回第一重複號碼找到(或None如果列表中不包含重複):

def get_first_duplicate(l): 
    s = set() 
    for x in l: 
     if x not in s: 
      s.add(x) 
     else: 
      return x 

get_first_duplicate([3, 5, 3]) 
# returns 3 

否則,如果你想獲得一個布爾回答這個問題:「這是否列表包含重複?」,你可以改爲返回它的重複元素:

def has_duplicates(l): 
    s = set() 
    for x in l: 
     if x not in s: 
      s.add(x) 
     else: 
      return true 
    return false 

get_first_duplicate([3, 5, 3]) 
# returns True 

senderle指出:

有人們有時會用這樣的邏輯壓縮成幾行的一個成語。我並不推薦它,但它是值得了解的:

s = set(); has_dupe = any(x in s or s.add(x) for x in l) 
+0

正如你可能知道的,有一種習慣用語,人們有時用這種習慣將這種邏輯壓縮成幾行。我不一定會推薦它,但值得一提的是:'s = set(); has_dupe = any(x in s或s.add(x)for x in lst)' – senderle

+0

@senderle我不知道它。我個人比較喜歡稀疏(vs密集)版本,但很高興知道它。我會將其添加到答案中;感謝你的分享。 –

2

可以使用collections.Counter()any()

>>> lis=[3,5,3] 
>>> c=Counter(lis) 
>>> any(x>1 for x in c.values()) # True means yes some value is repeated 
True 
>>> lis=range(10) 
>>> c=Counter(lis) 
>>> any(x>1 for x in c.values()) # False means all values only appeared once 
False 

或使用sets和匹配長度:

In [5]: lis=[3,3,5] 

In [6]: not (len(lis)==len(set(lis))) 
Out[6]: True 

In [7]: lis=range(10) 

In [8]: not (len(lis)==len(set(lis))) 
Out[8]: False 
+1

您返回問什麼OP正好相反 - 假時,有一個重複的,而不是真正。 – Junuxx

+0

只要在期望的基礎上添加'not',就可以很容易地進行修改,並且我在兩個註釋中解釋了「True」,「False」的含義。 –

+1

@Junuxx是對的,我認爲你應該解決這個問題。但是如果你解決了這個問題,這是一個很好的解決方案,因爲它通常比排序更快。 – senderle

4

首先,不要命名您的列表list。這是一個Python built-in,並將其用作變量名可能會產生不良副作用。我們將其稱爲L

您可以通過將該列表與自己的set版本進行比較來解決您的問題。

編輯:當重複,而不是周圍的其他方法你要真。代碼編輯。

def testlist(L): 
    return sorted(set(L)) != sorted(L) 
+2

+1簡單 –

0

無需額外的內存:

any(l.count(x) > 1 for x in l) 
+1

但慢 - O(n ** 2)而不是O(n)。 – senderle