python中的字谜列表列表

Posted

技术标签:

【中文标题】python中的字谜列表列表【英文标题】:list of lists of anagram in python 【发布时间】:2012-06-07 07:19:09 【问题描述】:

如果我的输入是这样的列表:

words = ['cat','act','wer','erw']

我想制作一个这样的字谜列表 -

[['cat','act'],['wer','erw']] 

我尝试过这样做:

[[w1 for w in words if w!=w1 and sorted(w1)==sorted(w)] for w1 in words]

但它不起作用。输出是:

[['cat'], ['act'], ['wer'], ['erw']]

此外,我不想使用任何导入(字符串除外)。什么错误?

【问题讨论】:

【参考方案1】:

请注意,您的原始方法实际上是 O(#words2) 时间,因此不适用于可能超过 10000 个单词的大型数据集。


groupby 单行:

itertools.groupby 见过的最优雅最奇怪的用例之一:

>>> [list(v) for k,v in groupby(sorted(words,key=sorted),sorted)]
[['cat', 'act'], ['wer', 'erw']]

defaultdict 三线:

使用collections.defaultdict,您可以:

anagrams = defaultdict(list)
for w in words:
    anagrams[tuple(sorted(w))].append(w)

至于如果在没有任何导入的情况下按照您的原始方式进行操作,您可以模拟collections.defaultdict,如下所示:

anagrams = 
for w in words:
    key = tuple(sorted(w))
    anagrams.setdefault(key,[]).append(w)

示例:

>>> anagrams
('e', 'r', 'w'): ['wer', 'erw'], ('a', 'c', 't'): ['cat', 'act']

(也写在whi's answer。)


ma​​p-reduce:

这个问题也是 map-reduce 的典型问题,您使用的归约键是排序后的字母(或者更有效的是哈希)。这将使您能够大规模并行化问题。


如果我们假设单词的长度是有界的,那么groupby 的解是O(#words log(#words)),而哈希解是O(#words)。在不太可能的情况下,单词的长度是任意的,排序(O(length log(length)) 每个单词)比使用与顺序无关的字母散列(O(length) 每个单词)效率低。遗憾的是,collections.Counter 不可散列,因此您必须自己编写。

【讨论】:

优雅简洁,可惜OP说没有使用任何import @NickCraig-Wood:啊,错过了;不过,我想我会把它留在这里以供将来参考。 是的,把它留在这里 - 这是一个很好的解决方案!【参考方案2】:
words = ['cat','act','wer','erw']
dic=
for w in words:
    k=''.join(sorted(w))
    dic.setdefault(k,[])
    dic[k].append(w)
print dic.values()

性能更好:O(n)

【讨论】:

dic.setdefault(k,[]).append(w) 的效率稍微高一些 - 省去了在字典中查找键两次【参考方案3】:

您可以通过谷歌搜索一次找到单个单词的字谜的各种解决方案。与明显的“搜索我知道的所有单词并查看它们是否具有相同的字母”相比,可能会有一个更有效的求解器。

一旦有了,就可以将其放入函数中:

def anagrams(word):
    "return a list of all known anagrams of *word*"

一旦你有了它,将它概括为一个单词列表是微不足道的:

[anagrams(word) for word in words]

【讨论】:

【参考方案4】:

这个应该是你喜欢的风格

[[w, w1] for w1 in words for w in words if w!=w1 and sorted(w1)==sorted(w)][::2]

【讨论】:

这是 O(len(words)**2) 所以如果有很多单词这会很慢。您已将 for w1 in words 嵌套在 for w in words 中。 @NickCraig-Wood 你是对的,这不是一个快速的解决方案,但它是“pythonic”:) 以及 [::2] 在你的 solotion 中是什么意思 @EyalDreifuss [::2] 表示从第一个元素开始,每隔一个元素取一个 @EyalDreifuss 为您解答,这部分[w1 for w in words if w!=w1 and sorted(w1)==sorted(w)] 仅获取每个元素并将它们中的每一个元素设为列表;即使在这种情况下,开头也应该是w 而不是w1,否则你只是从外部循环中获取w1

以上是关于python中的字谜列表列表的主要内容,如果未能解决你的问题,请参考以下文章

大型字谜搜索未读取到集合 Python 的末尾

确定一个列表是不是由 Java 8 中的字谜元素组成

Python-给定输入字母的可能的英语单字字谜

编写一个字谜查找器(来自 txt 文件中的单词列表)[重复]

Python中使用列表的字谜

字谜不匹配(字符串到列表),Python