2015-02-09 46 views
1

如果第一个字符串中的字母也包含在第二个字符串中,我希望能够返回True。例如,only_uses_letters_from("boffo","foobar")应返回True。以下是我迄今为止:在python中区分字符串

def only_uses_letters_from(x, y): 
    """returns true if the first string only contains characters that are also in the second string 

    str, str -> str""" 
    for letter in x: 
     if x in y: 
      return True 
    else: 
     return False 
+1

应该是'海峡,海峡 - > bool' BTW ... – 2015-02-09 01:11:01

回答

2

您可以使用set.issubset用来检查是否在每一个元素是B:

a, b = "boffo", "foobar" 
print(set(a).issubset(b)) 
True 

所以在你的函数:

def only_uses_letters_from(x, y): 
    return set(x).issubset(y) 

或者使用all,检查x中的每个字母是inb

def only_uses_letters_from(x, y): 
    return all(letter in y for letter in x) 

如果我们在x中找到一个不在y中的字母,并且返回False,如果所有字母都在y中,则所有将短路,则它将返回True。

如果您在使用集可以是一个快速的方式大量数据,以检查是否从一个迭代的任何元素是另一个:

def only_uses_letters_from(x, y): 
     st = set(y) # O(1) lookups 
     return all(letter in st for letter in x) 
+0

林在蟒蛇很新的,我感谢您抽出宝贵的时间来解释这对我来说,它实际上是有意义的 – holaprofesor 2015-02-09 00:23:12

+1

@JaredBanton,没有概率。真的没有太多。要成为另一个集合的子集,你的所有元素必须位于另一个集合中。使用'all'基本上就是说所有/每个元素必须在另一个迭代中。这两种方法都很好,特别是在处理查找速度非常快时,因此创建它的成本可以通过更大的数据抵消,并且可以使代码更加高效。 – 2015-02-09 00:28:45

+0

最后一种方法不一定是快速的:如果'x'很大并且不包含来自'y'的任何字母,那么它非常缓慢,因为它在整个字符串“x”中线性地变化。我建议首先,简单明了的解决方案*除非*速度是问题*并且*典型参数可以更快处理。 – EOL 2015-02-12 03:22:32

0

这里的方法是检查,对每一个字符x,它也在y。如果有一个字符这是不是这种情况,那么答案是False

def only_uses_letters_from(x, y): 
    for c in x: 
     if c not in y: 
      return False 
    return True 
+0

太棒了,它的工作!谢谢 – holaprofesor 2015-02-09 00:23:42

+0

这个解决方案手动执行'all()'是用来做什么的(参见Padraic的解决方案)。具体来说,这意味着使用这种解决方案会错过更短,更清晰的做同样事情的方式(更有效率,可能最重要的是)。 – EOL 2015-02-09 03:42:10

+1

@EOL是的,但这个答案有助于了解为什么最初的代码不起作用。我不认为每个SO回答都是用stdlib调用替换代码。 – 2015-02-10 10:04:03

0

你的代码逻辑有问题,如果第一个字母是字符串中,它将返回true的时候了。下面的代码将工作:

def foo(x, y): 
    for letter in x: 
     if letter not in y: 
      return False 
    return True 

print foo("booffo", "foobar") 
+2

您正在手动编写Python“all()”的功能。 – EOL 2015-02-09 03:43:49

-1

Python的方式:

def only_uses_letters_from(str1, str2): 
    return all(letter in str2 for letter in str1) 

这传达了你的逻辑,并使其可读。

不要使用set()优化大字符串!

有一些建议,当字符串很大时,用set()来预处理一个字符串以优化搜索。这是错误的。在集合中搜索更快,但创建集合本身比只搜索字符串要慢很多。

使用timeit表明,从字符串创建一个包含1.000.000个字母的集合在我的机器上花费了大约50毫秒,而运行原始函数的时间不到1毫秒。

python -m timeit -n 1000 -s setup='str2 = "".join("abc" for i in xrange(1000000))' 'set(str2)' 
+0

如果'str1'包含很多字母,并且它们都不在长字符串'str2'中,那么计时结果可能会给出相反的结果,因为在这种情况下,如果没有设置,Python必须遍历每一百万个字符在判断'str1'中的每个字符未被找到之前,'str2'。所以,我相信你的关于不使用'set()'的说法只适用于某些情况。 – EOL 2015-02-09 03:46:15