2015-06-20 35 views
2

我試圖通過一個數組並刪除python中不是anagrams的元素。這是我寫的代碼。我的邏輯看起來很好,但我似乎無法得到它。在Python中過濾數組中的Anagram

b = ['cat', 'dog', 'god', 'star', 'lap', 'act'] 
array=[] 
t=0 
for i in b: 
    while t<len(b): 
     if ''.join(sorted(i))==''.join(sorted(b[t])): 
      array.append(i) 
     t+=1 
print array 
+0

您的意思是說,數組中的所有元素都應該是結果中的字母? – shunya

回答

1

只需對現有代碼進行一些小的調整即可。

b = ['cat', 'dog', 'god', 'star', 'lap', 'act'] 
array = [] 
t = 0 
for i, value in enumerate(b): 
    t = i+1 
    while t<len(b): 
     if ''.join(sorted(value))==''.join(sorted(b[t])): 
      array.extend([value, b[t]]) 
     t+=1 
print array 
['cat', 'act', 'dog', 'god'] 
+0

OMG!謝謝!這很有道理; –

+0

歡迎。另外,如果它解決了您的問題,請接受答案。 – Akshay

+0

謝謝!我是這個網站的新手。 –

0
在你的程序

第一個問題,就是要初始化t0外的for循環中,因此你只用所有的元素檢查b的第一要素,爲for的迭代休息循環,t將總是大於len(b),因此它永遠不會進入內循環,從第二次迭代for循環。一個簡單的修正 -

for i in b: 
    t = 0 
    while t<len(b): 
     if ''.join(sorted(i))==''.join(sorted(b[t])): 
      array.append(i) 
     t+=1 

但尋找字謎,我覺得你是過於複雜,你可以簡單找出字符串的字符的ASCII值的總和,然後將它與其他比較相同的總和和長度,並檢查ASCII值和字符串長度的總和是否匹配,如果它們是字母表。此方法

實施例的代碼 -

b = ['cat', 'dog', 'god', 'star', 'lap', 'act'] 
c = list(map(len,b)) 
d = list(map(lambda x: sum([ord(c) for c in x]), b)) 
arr= [] 
for i, s in enumerate(b): 
    for j, s1 in enumerate(b): 
      if d[i] == d[j] and c[i] == c[j] and i != j: 
        if s not in arr: 
          arr.append(s) 
        if s1 not in arr: 
          arr.append(s1) 
print(arr) 
>> ['cat', 'act', 'dog', 'god'] 
+0

謝謝你的解釋和教訓! –

+0

歡迎。另外,請記住接受任何解決您問題的答案。會幫助社區很多 –

0

另一種方法

使用itertools GROUPBY

In [18]: from itertools import groupby 


In [19]: c=[list(g) for k,g in groupby(sorted(b,key=sorted),sorted)] 

In [20]: c 
Out[20]: [['cat', 'act'], ['lap'], ['star'], ['dog', 'god']] 

In [21]: [x for _list in c if len(_list)>1 for x in _list] 
Out[21]: ['cat', 'act', 'dog', 'god'] 

這裏的關鍵是使用itertools.groupby從迭代工具 將列表中的項目組合在一起的模塊。

我們提供給groupby的列表必須先進行排序,所以我們通過 它排序(b,key = sorted)。這裏的訣竅是,排序後的按鍵功能可以使用 ,並且會根據此函數的輸出進行排序,因此我們將 作爲按鍵功能再次排序,這將按順序使用字符串的字母對 單詞進行排序。我們不需要定義我們自己的函數或創建一個lambda函數 。

GROUPBY需要它用來告訴我們,如果項目應 組合在一起,並再次,我們可以只通過它內置的排序 功能鍵的功能。

來源:Finding and grouping anagrams by Python

+0

我想避免將圖書館用於實踐目的;無論如何,無論如何我都必須學習它,我感謝你的解釋和幫助!謝謝 –

0

其實你的解決方案是錯誤的,並使用2 for循環的想法是沒有效率的。你正在迭代你的列表2次,並在你的元素上應用''.join(sorted())兩個時間,你也在比較每個元素與它自己!而不是你可以使用字典來獲取字謎元素的索引與遍歷列表的enumerate

>>> d={} 
>>> for i,j in enumerate(b): 
... d.setdefault(''.join(sorted(j)),[]).append(i) 
... 
>>> d 
{'arst': [3], 'dgo': [1, 2], 'alp': [4], 'act': [0, 5]} 

>>> [b[t] for k in d.values() if len(k)>1 for t in k] 
['dog', 'god', 'cat', 'act'] 

如果你在乎的順序,你可以用OrderedDict功能從collections模塊:

>>> from collections import OrderedDict 
>>> d=OrderedDict() 
>>> for i,j in enumerate(b): 
... d.setdefault(''.join(sorted(j)),[]).append(i) 
... 
>>> [b[t] for k in d.values() if len(k)>1 for t in k] 
['cat', 'act', 'dog', 'god'] 
+1

謝謝!雖然這不是我正在尋找的,但我從你的回答中學到了很多東西。 OMG! –