2015-02-09 45 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