Python 基本字谜与更高级的字谜

Python 基本字谜与更高级的字谜,python,python-2.7,python-3.x,Python,Python 2.7,Python 3.x,我目前正在研究一个“列表”单元,在其中一个练习中,我们需要创建一个字谜(对于那些不知道的人来说;如果你能将字母从一个重新排列到另一个,两个单词就是一个字谜) 想到的简单解决方案是: def is_anagram(a, b): return sorted(a) == sorted(b) print is_anagram('god', 'dog') 这很有效,但我并不满意。例如,如果我们处于这种情况: def is_anagram(a, b): return sorted(a)

我目前正在研究一个“列表”单元,在其中一个练习中,我们需要创建一个字谜(对于那些不知道的人来说;如果你能将字母从一个重新排列到另一个,两个单词就是一个字谜)

想到的简单解决方案是:

def is_anagram(a, b):
    return sorted(a) == sorted(b)

print is_anagram('god', 'dog')
这很有效,但我并不满意。例如,如果我们处于这种情况:

def is_anagram(a, b):
    return sorted(a) == sorted(b)

print is_anagram('god', 'dyog') #extra letter 'd' in second argument
>>> False
Return是False,尽管我们应该能够用
'dyog'
构建单词
'god'
。也许这个游戏/问题不被称为字谜,但我一直在努力解决它

从技术上讲,我的解决方案是:
1-迭代b的每个元素。
2-正如我所做的,我检查a中是否存在该元素。
3-如果所有人都这样做;然后我们可以从b中创建a。
4-否则,我们不能

我就是不能让它工作记录在案,我不知道如何使用
lambda

一些测试:

print is_anagram('god', 'ddog') #should return True
print is_anagram('god', '9d8s0og') #should return True
print is_anagram('god', '_@10d_o g') #should return True
谢谢:)

试试看:

def is_anagram(a, b):
    word = [filter(lambda x: x in a, sub) for sub in b]
    return ''.join(word)[0:len(a)]
例如:

>>> is_anagram('some','somexcv')
'some'
注意:此代码返回
常用词(如果有)或
,否则返回。(它不会像OP所问的那样返回
True/False
——意识到这之后,但无论如何,这个代码可以很容易地改变以适应
True/False
类型的结果——我现在不会修复它,因为在这篇文章中已经有了很好的答案:))

简要说明:

此代码也会对
a
单词中存在的
b
单词上的每个字母(
sub
)进行(
filter
)。最后返回必须与a具有相同长度的单词(
[0:len(a)]
)。带有
len
的最后一部分需要这样的案例:
是一个字谜('some','somenothing')
如果您需要检查
a
单词是否可以从
b
创建,您可以这样做

def is_anagram(a,b):
    b_list = list(b)
    for i_a in a:
        if i_a in b_list:
            b_list.remove(i_a)
        else:
            return False
    return True
更新(解释)

b_list=list(b)
制作
str
对象(字符)的
list

答案中的基本情况是:我们检查
a
b_列表中列出的每个字符,当出现时,我们将该字符从
b_列表中删除(我们这样做是为了消除通过输入
'good'
'good'
返回
True
的可能性)。因此,如果在
b_列表
的其余部分中没有出现另一个
a
字符,那么它就不是高级字谜

def is_anagram(a, b):
    test = sorted(a) == sorted(b)
    testset = b in a
    testset1 = a in b
    if testset == True:
        return True
    if testset1 == True:
        return True
    else:
        return False

不比其他解决方案好多少。但如果你喜欢冗长的代码,这里是我的

由于其他答案在撰写本文时不支持颠倒顺序:

包含方便,因为为什么不

# Just strip hints out if you're in Python < 3.5.
def is_anagram(a: str, b: str) -> bool:
    long, short = (a, b) if len(a) > len(b) else (b, a)
    cut = [x for x in long if x in short]
    return sorted(cut) == sorted(short)

我认为所有这些分类都是在转移注意力;这些信件应该被计算在内

def is_anagram(a, b):
    return all(a.count(c) <= b.count(c) for c in set(a))

迭代
b
是不可避免的,因为您需要计算那里的所有字母。如果在
a
中找不到一个字符,这将立即退出,因此我认为您无法对该算法进行太多改进。

因此,您需要检查
a
字符串是否可以从
b
中生成?它是否需要在两个方向上工作?例如,
is_anagram('dyog','god')
是否应该返回
True
,就像相反的那样?还是有必要下订单?这没什么变化,但我在下面看到的答案并没有改变。@vishes_shell是的,先生。@DavidHeyman,任何命令和任何情况。顺便说一句,
lambda
相当简单-
lambda x:x在a
中与
def foo(x):在a中返回x相同,只是没有给出它的实际名称,因此,您必须将其作为参数传递,或将其分配给变量。可以有任意数量的论点,但正文必须是一条语句。@Jean-Françoisfare修正了这个问题。@vishes_shell,谢谢你。我将探索并研究它,但它确实通过了所有测试:)感谢您的帮助。@Vayl很高兴它起了作用。这非常有效!只是一个问题,你为什么使用
b_list=list(b)
-这里发生了什么变化?@Vayl我已经更新了答案并进行了解释,如果你有任何问题,请随时提问。谢谢你的回答。恐怕我不能真正理解它。从未使用过
lambda
,而且你的代码对我来说太紧了:)@Vayl,我本想帮你,我真的很想解释一下代码,但因为你以前从未使用过lambda,所以我无法在一篇帖子中做到这一点。。。无论如何,谢谢你的反馈:)无论如何,我很感激!大卫,明天早上我会以一种全新的思维来回顾这个答案和你的评论。非常感谢:)
是一个字谜('god','ddog')
应该返回
True
# Again, strip hints out if you're in Python < 3.5.
def is_anagram(a: str, b: str) -> bool:
    long, short = (a, b) if len(a) > len(b) else (b, a)
    # Parentheses around lambda are not necessary, but may help readability
    cut = filter((lambda x: x in short), long)
    return sorted(cut) == sorted(short)
def is_anagram(a, b):
    return all(a.count(c) <= b.count(c) for c in set(a))
from collections import defaultdict

def is_anagram(a, b):
    b_dict = defaultdict(int)

    for char in b:
        b_dict[char] += 1

    for char in a:
        b_dict[char] -= 1
        if b_dict[char] < 0:
            return False

    return True