for 循环的替代品 |如何检查单词是否包含不同单词的一部分
Alternative to for loops | How to check if word contains part of a different word
如果你检查下面的代码,我使用循环来检查一组单词中是否有一个单词是另一个单词的后缀。
我的问题是,如何替换双 for 循环?写这个任务的人提到有一个使用算法的解决方案(不知道那是什么:/)
def checkio(words):
if len(words) == 1: return False
else:
for w1 in words:
for w2 in words:
if w1 == w2:
continue
elif w1.endswith(w2) or w2.endswith(w1): return True
else: return False
print checkio({"abc","cba","ba","a","c"}) # prints True in Komodo
print checkio({"walk", "duckwalk"}) # prints True
第二个问题:
看来当前功能并不适用于所有环境。
有人可以指出我做错了什么吗?它适用于我的 Komodo IDE 但不适用于 chekio 网站。
这里有一个 link 任务:http://www.checkio.org/mission/end-of-other/
Python 的 str.endswith() 会完成这项工作。
示例脚本:
>>> a = 'hello'
>>> a.endswith('llo')
True
>>> a.endswith('ello')
True
>>> a.endswith('o')
True
>>> a.endswith('lo')
True
>>> a.endswith('ell')
False
包装到一个函数:
import itertools
def checkio(words):
words = [ w for w, s in itertools.product(words, words) if w != s and ( w.endswith(s) or s.endswith(w) ) ]
return False if len(words) == 0 else True
示例输出: You can test it here:
checkio( {"hello", "lo", "he"} ) => True
checkio( {"hello", "la", "hellow", "cow"} ) => False
checkio( {"walk", "duckwalk"} ) => True
checkio( {"one"} ) => False
checkio( {"helicopter", "li", "he"} ) => False
让Python生成所有要检查的组合:
import itertools
def checkio(data):
return any((x.endswith(y) or y.endswith(x)) for x, y in itertools.combinations(data, 2))
让Python测试一下:
assert checkio({"abc","cba","ba","a","c"}) == True
assert checkio({"walk", "duckwalk"}) == True
assert checkio({"aaa", "bbb"}) == False
可以使用交集和理解:
def checkio(words):
for w in words:
ends = {w[i:] for i in range(1,len(w))}
if len(words & ends) > 0:
return True
return False
输出:
>>> checkio({"walk", "duckwalk"})
True
>>> checkio({"walk", "duckbill"})
False
其工作方式如下。假设 words
包含单词 'scared'。当 w
为 'scared' 时,切片集 ends
变为 {'cared'、'ared'、'red'、'e'、'd'}。 & 是 Python 的交集运算符。如果任何单词对于 words
和 ends
都是通用的,例如'red',这个交集将是非空的,因此 len(words & ends) > 0
将是 True
—— 然后作为函数值返回。如果代码成功循环遍历所有单词而没有遇到 len(words & ends) > 0
,列表中没有一个单词作为另一个单词后缀的示例,因此返回 False
。
这是使用 itertools.combinations()
的 for 循环版本:
def checkio(words):
for w1, w2 in itertools.combinations(words, 2):
if w1.endswith(w2) or w2.endswith(w1):
return True
return False
print checkio({"abc","cba","ba","a","c"}) # prints True in Komodo only :/
print checkio({"walk", "duckwalk"}) # prints True
print checkio({"a", "foo", "bar"}) # prints False
给予:
True
True
False
如果您打印每次迭代,您将看到 combinations()
函数的工作原理,因此对于最后一个示例,您将看到它尝试以下操作:
a - foo
a - bar
foo - bar
谢谢大家,你们所有的评论和回复帮助我以不同的方式看待它。我认为这段代码不那么笨重和清晰,不需要模块导入
def checkio(words):
for w1 in words:
for w2 in words:
if w1 != w2 and (w1.endswith(w2) or w2.endswith(w1)):
return True
return False
如果你检查下面的代码,我使用循环来检查一组单词中是否有一个单词是另一个单词的后缀。
我的问题是,如何替换双 for 循环?写这个任务的人提到有一个使用算法的解决方案(不知道那是什么:/)
def checkio(words):
if len(words) == 1: return False
else:
for w1 in words:
for w2 in words:
if w1 == w2:
continue
elif w1.endswith(w2) or w2.endswith(w1): return True
else: return False
print checkio({"abc","cba","ba","a","c"}) # prints True in Komodo
print checkio({"walk", "duckwalk"}) # prints True
第二个问题: 看来当前功能并不适用于所有环境。 有人可以指出我做错了什么吗?它适用于我的 Komodo IDE 但不适用于 chekio 网站。
这里有一个 link 任务:http://www.checkio.org/mission/end-of-other/
Python 的 str.endswith() 会完成这项工作。
示例脚本:
>>> a = 'hello'
>>> a.endswith('llo')
True
>>> a.endswith('ello')
True
>>> a.endswith('o')
True
>>> a.endswith('lo')
True
>>> a.endswith('ell')
False
包装到一个函数:
import itertools
def checkio(words):
words = [ w for w, s in itertools.product(words, words) if w != s and ( w.endswith(s) or s.endswith(w) ) ]
return False if len(words) == 0 else True
示例输出: You can test it here:
checkio( {"hello", "lo", "he"} ) => True
checkio( {"hello", "la", "hellow", "cow"} ) => False
checkio( {"walk", "duckwalk"} ) => True
checkio( {"one"} ) => False
checkio( {"helicopter", "li", "he"} ) => False
让Python生成所有要检查的组合:
import itertools
def checkio(data):
return any((x.endswith(y) or y.endswith(x)) for x, y in itertools.combinations(data, 2))
让Python测试一下:
assert checkio({"abc","cba","ba","a","c"}) == True
assert checkio({"walk", "duckwalk"}) == True
assert checkio({"aaa", "bbb"}) == False
可以使用交集和理解:
def checkio(words):
for w in words:
ends = {w[i:] for i in range(1,len(w))}
if len(words & ends) > 0:
return True
return False
输出:
>>> checkio({"walk", "duckwalk"})
True
>>> checkio({"walk", "duckbill"})
False
其工作方式如下。假设 words
包含单词 'scared'。当 w
为 'scared' 时,切片集 ends
变为 {'cared'、'ared'、'red'、'e'、'd'}。 & 是 Python 的交集运算符。如果任何单词对于 words
和 ends
都是通用的,例如'red',这个交集将是非空的,因此 len(words & ends) > 0
将是 True
—— 然后作为函数值返回。如果代码成功循环遍历所有单词而没有遇到 len(words & ends) > 0
,列表中没有一个单词作为另一个单词后缀的示例,因此返回 False
。
这是使用 itertools.combinations()
的 for 循环版本:
def checkio(words):
for w1, w2 in itertools.combinations(words, 2):
if w1.endswith(w2) or w2.endswith(w1):
return True
return False
print checkio({"abc","cba","ba","a","c"}) # prints True in Komodo only :/
print checkio({"walk", "duckwalk"}) # prints True
print checkio({"a", "foo", "bar"}) # prints False
给予:
True
True
False
如果您打印每次迭代,您将看到 combinations()
函数的工作原理,因此对于最后一个示例,您将看到它尝试以下操作:
a - foo
a - bar
foo - bar
谢谢大家,你们所有的评论和回复帮助我以不同的方式看待它。我认为这段代码不那么笨重和清晰,不需要模块导入
def checkio(words):
for w1 in words:
for w2 in words:
if w1 != w2 and (w1.endswith(w2) or w2.endswith(w1)):
return True
return False