Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的字谜列表_Python_Python 2.7_Anagram - Fatal编程技术网

python中的字谜列表

python中的字谜列表,python,python-2.7,anagram,Python,Python 2.7,Anagram,如果我的输入是这样的列表: 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']] 此外,我不想使用任何导入(字符串除外)。错在

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

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']]

此外,我不想使用任何导入(字符串除外)。错在哪里?

通过谷歌搜索,你可以一次找到一个单词的各种拼法。很可能会有一个比显而易见的“搜索我知道的所有单词,看看它们是否有相同的字母”更有效的解决方法

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

def anagrams(word):
    "return a list of all known anagrams of *word*"
一旦你做到了这一点,把它概括成一系列的单词是很简单的:

[anagrams(word) for word in words]

请注意,您最初的方法实际上是O(#words2)时间,因此无法处理可能超过10000个单词的大型数据集


一行分组:

这是我所见过的
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']}
(也写在了)


地图缩小:

这个问题也是map reduce的poster子级,其中使用的归约键是已排序的字母(或者更有效地说,是散列)。这将允许您大规模并行化问题


如果我们假设单词的长度是有界的,
groupby
解决方案是
O(#单词日志(#单词))
,而散列解决方案应该是
O(#单词)
。在不太可能的情况下,单词的长度是任意的,排序(
O(长度日志(长度))
每个单词)的效率低于使用字母的顺序无关散列(
O(长度)
)。遗憾的是,collections.Counter是不可散列的,所以您必须自己编写

words = ['cat','act','wer','erw']
dic={}
for w in words:
    k=''.join(sorted(w))
    dic.setdefault(k,[])
    dic[k].append(w)
print dic.values()

这在perform:O(n)

中更好。这一个应该按照您喜欢的样式来做

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

优雅简洁,但不幸的是OP没有使用任何import@NickCraig-伍德:啊,错过了;我想我会把它放在这里以备将来参考。是的,把它放在这里-这是一个伟大的解决方案!写
dic稍微更有效。setdefault(k,[])。append(w)
-保存在字典中查找两次键这是O(len(words)**2),因此如果有很多单词,这将非常缓慢。您已将w1的
嵌套在words中
中,而w的
嵌套在words中@NickCraig Wood您是对的,这不是一个快速解决方案,但它是“pythonic”:)以及[::2]在您的sulotion@EyalDreifuss[::2]表示从第一个元素开始,每秒钟element@EyalDreifuss对于您的答案,这部分
[w1表示w,如果w!=w1和sorted(w1)==sorted(w)]
只获取每个元素,并将它们作为一个列表;即使在这种情况下,它也应该是
w
而不是开头的
w1
,否则您只是从外部循环获取
w1