2015-10-07 60 views
0

我正在嘗試編寫一個Python函數,用於統計列表中只出現一次的條目數。計數發生1次列表條目的數量

例如,給出的列表[17],該函數將返回1或給予[3,3,-22,1,-22,1,3,0],它將返回1.

**限制:我無法將任何東西導入到我的程序中。

到目前爲止我寫的不正確的代碼:我要去雙循環路線,但指數數學變得過於複雜。

def count_unique(x): 
    if len(x) == 1: 
    return 1 
    i = 0 
    j = 1 
    for i in range(len(x)): 
    for j in range(j,len(x)): 
     if x[i] == x[j]: 
     del x[j] 
     j+1 
    j = 0 
    return len(x) 
+0

你能爲此顯示你的代碼嗎?你試過什麼了? – idjaw

+0

@idjaw請參閱編輯。這是非常錯誤的,但這是我目前所擁有的 – freezefry

回答

2

一個更簡單易懂的解決方案:

l = [3, 3, -22, 1, -22, 1, 3, 0] 
counter = 0 

for el in l: 
    if l.count(el) == 1: 
     counter += 1 

這很簡單。您遍歷列表中的項目。然後你看看該元素是否恰好在列表中的一次,然後添加+1。您可以改進代碼(使聽衆理解,使用lambda表達式等),但這是所有背後的理念,也是最容易理解的imo。

+1

儘管與其他解決方案不同,它確實意味着'O(n^2)'工作;你明確地迭代列表,並且對於其中的每個項目都隱式地重複。對於大型列表,這將是非常昂貴的。基於dict的解決方案在'O(n)'時間運行。 – ShadowRanger

+0

是的,這不是最快的解決方案。我從未聲稱過。我只聲稱這很容易理解。我覺得OP需要的不是爲此做一些高級算法。但是我很高興能在這裏得到所有好的答案,這也將成本考慮在內!有幾個可以upvote。一些很棒的解決方案,也是一個雙重過濾器:) – colidyre

+0

我沒有看到比O(n^2)更好的解決方案。 –

3
lst = [3,3,-22,1,-22,1,3,0] 
len(filter(lambda z : z[0] == 1, 
      map(lambda x : (len(filter(lambda y : y == x, lst)), x), lst))) 

對不起:)

您的解決方案不起作用,因爲你正在做的事情很奇怪。在迭代中刪除列表中的內容時,j + 1沒有意義。嘗試添加對新列表唯一的元素,然後計算其中的內容數量。然後找出我的解決方案。

這裏是O(n)的解決方案BTW:

lst = [3,3,-22,1,-22,1,3,0,37] 
cnts = {} 
for n in lst: 
    if n in cnts: 
     cnts[n] = cnts[n] + 1 
    else: 
     cnts[n] = 1 

count = 0 
for k, v in cnts.iteritems(): 
    if v == 1: 
     count += 1 
print count 
+0

你能想出一個更簡單的解決方案嗎?我不明白這一點.. – freezefry

+0

pythonic但複雜... – hsfzxjy

+0

你能做得更好嗎?使用計數是作弊(我不知道它存在,我在Python中識字) –

2

既然你不能使用collections.Countersorted/itertools.groupby明顯(其中一個通常將是我轉到解決方案,這取決於是否輸入是可哈希或排序),只是模擬大致相同的行爲,爲Counter,計數所有的元素,然後計數,在端部只出現一次的元素數:

def count_unique(x): 
    if len(x) <= 1: 
     return len(x) 
    counts = {} 
    for val in x: 
     counts[val] = counts.get(val, 0) + 1 
    return sum(1 for count in counts.values() if count == 1) 
1
There is method on lists called count.... from this you can go further i guess. 
for example: 

for el in l: 
    if l.count(el) > 1: 
     continue 
    else: 
     print("found {0}".format(el)) 
+0

也許你應該迭代set(l)而不是l。 – hsfzxjy

2

你使這個過於複雜。嘗試使用一個字典,其中鍵是列表中的元素。這種方式,如果它存在將是唯一的

要添加到此。當考慮複雜性時,它可能是最好的方法。一個in字典上的查找被認爲是O(1),for循環是O(n)所以總的時間複雜度是O(n)這是可取的...使用列表元素count()在整個列表上搜索每個元素,基本上是O(n^2) ...那是壞的

from collections import defaultdict 
count_hash_table = defaultdict(int) # i am making a regular dictionary but its data type is an integer 
elements = [3,3,-22,1,-22,1,3,0] 
for element in elements: 
    count_hash_table[element] += 1 # here i am using that default datatype to count + 1 for each type 

print sum(c for c in count_hash_table.values() if c == 1):