在 Python 中过滤数组中的 Anagram
Posted
技术标签:
【中文标题】在 Python 中过滤数组中的 Anagram【英文标题】:Filter Anagram in Array in Python 【发布时间】:2015-09-06 04:52:25 【问题描述】:我正在尝试遍历一个数组并删除 python 中不是字谜的元素。这是我写的代码。我的逻辑似乎很好,但我似乎无法理解。
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
【问题讨论】:
你的意思是数组中的所有元素都应该是结果中的字谜? 【参考方案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']
【讨论】:
天哪!谢谢!这很有意义; 欢迎。另外,如果它解决了您的问题,请接受答案。 谢谢!我是这个网站的新手。【参考方案2】:您的程序中的第一个问题是您在 for 循环之外将 t
初始化为 0
,因此您只需检查 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']
【讨论】:
谢谢你的解释和教训! 欢迎。另外,请记住接受任何解决了您问题的答案。对社区有很大帮助【参考方案3】:另一种方法
使用 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 中的 itertools.groupby 将列表中的项目组合在一起的模块。
我们提供给 groupby 的列表必须预先排序,所以我们通过 它已排序(b,key=sorted)。这里的诀窍是 sorted 可以采取 key 函数,并将根据该函数的输出进行排序,所以 我们再次通过 sorted 作为 key 函数,这将对 单词按顺序使用字符串的字母。没必要 定义我们自己的函数或创建一个 lambda。
groupby 有一个关键函数,它用来判断项目是否应该 组合在一起,我们可以再次将其传递给内置的 sorted 功能。
来源:Finding and grouping anagrams by Python
【讨论】:
我想避免将库用于练习目的;无论如何,无论如何我都必须学习它,感谢您的解释和帮助!谢谢【参考方案4】:实际上您的解决方案是错误的,使用 2 for
循环的想法效率不高。您正在迭代您的列表 2 次并在您的元素上应用 ''.join(sorted())
2 次,而且您正在将每个元素与其自身进行比较!相反,您可以使用字典通过迭代列表的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']
如果你关心订单,你可以使用collections
模块中的OrderedDict
函数:
>>> 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']
【讨论】:
谢谢!虽然这不是我想要的,但我确实从您的回复中学到了很多东西。以上是关于在 Python 中过滤数组中的 Anagram的主要内容,如果未能解决你的问题,请参考以下文章