在 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的主要内容,如果未能解决你的问题,请参考以下文章

试图想出python anagram函数

提高 anagram string 函数的时间效率

过滤数组中的子数组

从矩形中提取文本时的 ItextSharp anagram 输出

在 tableView 中显示过滤数组中的数据

过滤和删除数组中的过滤元素