从单词列表中创建字谜列表

时间:2015-05-14 19:58:41

标签: python list anagram

我想从单词列表中找到字谜的创建列表。我应该在代码或递归中使用另一个循环吗?

some_list = ['bad', 'app', 'sad', 'mad', 'dab','pge', 'bda', 'ppa', 'das', 'dba']

new_list = [some_list[0]]
i = 0
while i+1 < len(some_list):
    if (''.join(sorted(some_list[0]))) == (''.join(sorted(some_list[i+1]))):
        new_list.append(some_list[i+1])
        i = i+1
    else:
        i = i+1

print(new_list)
  • 我的输出是['bad', 'dab', 'bda', 'dba']。但我也想要更多名单 来自some_list的其他字谜。

我希望输出为:   - ['app', 'ppa']   - ['bad', 'dab', 'bda', 'dba']   - ['sad', 'das']

7 个答案:

答案 0 :(得分:5)

我建议您编写Python,而不是Java或其他任何您正在仿效的语言。这是你在Python中的核心代码,具有正常的循环,没有所有不必要的东西:

new_list = [some_list[0]]
for word in some_list[1:]:
    if sorted(some_list[0]) == sorted(word):
        new_list.append(word)

我没有看到用于递归,但是,你可以在它周围包裹一个外环以找到其他的anagram组。

虽然我是这样做的,但请使用有用的itertools.groupby

for _, group in groupby(sorted(some_list, key=sorted), sorted):
    group = list(group)
    if len(group) > 1:
        print(group)

打印:

['bad', 'dab', 'bda', 'dba']
['sad', 'das']
['app', 'ppa']

通过对组进行排序来更改问题的替代解决方案:

groups = (list(group) for _, group in groupby(sorted(some_list, key=sorted), sorted))
print([group for group in sorted(groups) if len(group) > 1])

输出:

[['app', 'ppa'], ['bad', 'dab', 'bda', 'dba'], ['sad', 'das']]

答案 1 :(得分:3)

您的问题是您在列表上循环一次,因为您需要根据所有单词进行循环。

但我建议采用另一种方式完成此任务,您可以使用itertools.groupby并使用operator.itemgetter排序函数:

some_list = ['bad', 'app', 'sad', 'mad', 'dab','pge', 'bda', 'ppa', 'das', 'dba']

from operator import itemgetter
from itertools import groupby 
s=sorted([(i,''.join(sorted(j))) for i,j in enumerate(some_list)],key=itemgetter(1))
inds= [zip(*g)[0] for _,g in groupby(s,itemgetter(1))]
print [itemgetter(*i)(some_list) for i in inds]

结果:

[('bad', 'dab', 'bda', 'dba'), 'mad', ('sad', 'das'), ('app', 'ppa'), 'pge']

我在这里所做的就是使用sortedenumerate创建一个带有这些索引的已排序单词列表:

sorted([(i,''.join(sorted(j))) for i,j in enumerate(some_list)],key=itemgetter(1))
[(0, 'abd'), (4, 'abd'), (6, 'abd'), (9, 'abd'), (3, 'adm'), (2, 'ads'), (8, 'ads'), (1, 'app'), (7, 'app'), (5, 'egp')]

然后我们需要根据第二个元素对这些对进行分组并得到第一个元素(索引),这样我们将得到以下元组列表:

[(0, 4, 6, 9), (3,), (2, 8), (1, 7), (5,)]

每个元组都包含那些排序表示相同的单词的索引。

最后您需要的是根据前面的索引获取主列表的元素:

[itemgetter(*i)(some_list) for i in inds]
[('bad', 'dab', 'bda', 'dba'), 'mad', ('sad', 'das'), ('app', 'ppa'), 'pge']

答案 2 :(得分:0)

1)创建一个函数anagrams(word),它会为您的代码返回单个单词的字谜列表。
2)map对你的单词列表的功能。

答案 3 :(得分:0)

这是一个解决方案:

from itertools import groupby
some_list = ['bad', 'app', 'sad', 'mad', 'dab','pge', 'bda', 'ppa', 'das', 'dba']
some_list_ordered = map( lambda x : "".join( sorted( x) ), some_list )
some_lists = sorted(zip( some_list_ordered, some_list ) )
anagrams = filter( lambda x : len( x ) > 1, [ zip(*v)[1]  for k,v in groupby( some_lists, lambda x : x[0] ) ] )    

for a in anagrams:
    print a

#('bad', 'bda', 'dab', 'dba')
#('das', 'sad')
#('app', 'ppa')

答案 4 :(得分:0)

如果你能负担额外字典的内存开销,那么自然的方法似乎是:

words = ['bad', 'app', 'sad', 'mad', 'dab','pge', 'bda', 'ppa', 'das', 'dba']

anagrams = {}
for word in words:
    sword = ''.join(sorted(word))
    try:
        anagrams[sword].append(word)
    except KeyError:
        anagrams[sword] = [word]

anagrams_list = [v for v in anagrams.values() if len(v) > 1]
print anagrams_list

输出:

[['app', 'ppa'], ['bad', 'dab', 'bda', 'dba'], ['sad', 'das']]

编辑:如下面的评论所述,如果语法不打扰您,可以使用try...except方法dict替换setdefault块:

words = ['bad', 'app', 'sad', 'mad', 'dab','pge', 'bda', 'ppa', 'das', 'dba']

anagrams = {}
for word in words:
    sword = ''.join(sorted(word))
    anagrams.setdefault(sword, []).append(word)

anagrams_list = [v for v in anagrams.values() if len(v) > 1]
print anagrams_list

答案 5 :(得分:0)

您可以使用排序后的单词作为键对单词中的单词进行分组,过滤掉没有至少两个元素的单词,使用OrderedDict保持顺序:

some_list = ['bad', 'app', 'sad', 'mad', 'dab','pge', 'bda', 'ppa', 'das', 'dba']


from collections import OrderedDict

od = OrderedDict()
for ele in some_list:
    srt = "".join(sorted(ele))
    od.setdefault(srt,[]).append(ele)

print(filter(lambda x: len(x) > 1, od.values()))


[['bad', 'dab', 'bda', 'dba'], ['app', 'ppa'], ['sad', 'das']]

或者使用循环并附加到列表,使用临时列表来收集常用词:

new_list = []
from collections import OrderedDict
for ele in OrderedDict.fromkeys("".join(sorted(ele)) for ele in some_list):
    temp = []
    for s in some_list:
        if ele == ''.join(sorted(s)):
            temp.append(s)
    if len(temp) > 1:
        new_list.append(temp)

如果订单无关紧要,defaultdict会更有效:

from collections import defaultdict

d = defaultdict(list)
for ele in some_list:
    d[''.join(sorted(ele))].append(ele)

print(filter(lambda x: len(x) > 1, d.values()))
[['app', 'ppa'], ['bad', 'dab', 'bda', 'dba'], ['sad', 'das']]

答案 6 :(得分:-1)

https://username:password@git-repo/repo.git

#create a new remote with the authenticated url
git remote set-url authrepo https://username:password@git-repo.com/repo.git

#delete the old remote
git remote remove <your ocurrent remote>

#call the old remote the same as new remote
git remote rename authrepo <your current remote>