写了一个作业,比较两个单词,看前一个单词能否用后一个单词中的字母拼接出来。 Your task will be to write a function can_be_composed(word1, word2) to check if word1 can be composed from word2 . Put your function into a file compose.py. Example usages: • can_be_composed("python", "pantyhose") returns True • can_be_composed("python", "ponytail") returns False • can_be_composed("code", "docent") returns True • can_be_composed("messy", "reassembly") returns True • can_be_composed("computational", "alphanumeric") returns False • can_be_composed("linguistics", "criminologists") returns False
思路是先把单词转换成 dict,然后再比较, import collections def word2dict(word):
word2dict=dict(collections.Counter(word))
return word2dict
def can_be_composed(word1,word2): dw1=word2dict(word1) dw2=word2dict(word2)
for key in dw1.keys():
if key in list(dw2.keys()) and dw1[key] <= dw2[key]:
return True
else:
return False
但是我每次得出的都是 True,后来发现, for key in dw1.keys(): if key in list(dw2.keys()) and dw1[key] <= dw2[key]: return True
这得出的结果是每个 key 的值的比较,输出的是一系列的对比结果,
问题来了,对于 if key in list(dw2.keys()) and dw1[key] <= dw2[key]:,如何能够在对比只要得出 false 就输出 false,只有全部都是 True 才输出 true ?
或者有没有更简单的方法?
附上原题, Exercise 3. We will say that a word “can be composed” from another word if it is possible to select some of the letters from the second word (maybe all of them) to build the first one (possibly changing the order). For example, word “python” can be composed from words “pantyhose”, “immunotherapy”, or “hypnotists”. It can not be composed from word “ponytail” because “ponytail” does not have a letter “h”. Similarly, word “lesson” can be composed from “professional” or “responsible”, but it can not be composed from word “longest” as “longest” does not have enough “s” letters. Your task will be to write a function can_be_composed(word1, word2) to check if word1 can be composed from word2 . Put your function into a file compose.py. Example usages: • can_be_composed("python", "pantyhose") returns True • can_be_composed("python", "ponytail") returns False • can_be_composed("code", "docent") returns True • can_be_composed("messy", "reassembly") returns True • can_be_composed("computational", "alphanumeric") returns False • can_be_composed("linguistics", "criminologists") returns False Hint: Write a function word2dict(word) which will convert word to a dictionary with an information how many times every letter occured in word . Use word2dict in your can_be_composed function.
1
ipwx 2019-11-28 23:35:30 +08:00 1
>>> def can_be_composed(a, b):
... a_count = collections.Counter(a) ... b_count = collections.Counter(b) ... return all(a_count[k] <= b_count.get(k, 0) for k in a_count) |
3
cherbim 2019-11-28 23:52:36 +08:00
你知道你为啥每次都输出 True 呢,for 循环里面,return 直接返回值,停止方法,比如第一次循环,第一个单词第一个字母如果在第二个单词里,你 return true,直接这个方法就停止了,然后返回 ture,如果没有,返回 false,后面的都没比较,修改一下:return true 要放在 for 循环外面,return flase 放在 for 循环内部 ,判断字母在不在第二个里面 ,如果不在 return flase 如果在就 pass
|
4
cherbim 2019-11-29 00:00:44 +08:00
@ryanjmliao dict.get(key, default=None) key -- 字典中要查找的键 default -- 如果指定键的值不存在时,返回该默认值 0 表示如果不存在返回 0,可以自己设定返回值
|
5
ibirdyuan 2019-11-29 00:11:28 +08:00 2
def can_be_composed(a, b):
if set(a) - set(b): return False else: return True |
6
ljpCN 2019-11-29 00:21:08 +08:00 via Android 1
@ibirdyuan 还可以写得更 Python 一点
>>> def can_be_composed(a, b): ... return False if set(a) - set(b) else True |
7
noqwerty 2019-11-29 00:37:00 +08:00 via Android 1
@ibirdyuan 这样应该不行吧,原题的要求是还要有足够数量的字母,比如 a 需要两个 y 而 b 只有一个 y 的话也会返回 False
|
9
ibirdyuan 2019-11-29 00:40:11 +08:00
@noqwerty 你是对的,刚没看原题,以为就是一个判断子集的问题。
刚发现原题有一句 Similarly, word “lesson” can be composed from “professional” or “responsible”, but it can not be composed from word “longest” as “longest” does not have enough “s” letters. |
10
festoney8 2019-11-29 01:59:10 +08:00
word2 中逐个踢掉 word1 字母
|
11
dji38838c 2019-11-29 04:41:59 +08:00 2
搞那么多 bool, if 的干什么,集合里难道会没有子集的 operation 吗
return set(b).issubset(set(a)) |
12
ryanccq 2019-11-29 08:24:05 +08:00 via iPhone 1
def can_be_composed(word1, word2):
return all([word1.count(i) <= word2.count(i) for i in word1]) |
13
hell0v2 2019-11-29 08:54:48 +08:00
11 楼正式我想说的,不应该是思路问题么,这种情况用什么字典。。。
|
14
yucongo 2019-11-29 12:14:51 +08:00 1
check = lambda x, y: all([y.count(elm) >= x.count(elm) for elm in x])
check("python", "pantyhose") # True check('lesson', 'professional') # True check('lesson', 'responsible') # True check('lesson', 'longest') # False |
15
ipwx 2019-11-29 12:22:36 +08:00 via Android
楼上一堆没审题就来逼逼用集合差的家伙。
|
16
imn1 2019-11-29 12:25:52 +08:00
我建议变量 word2dict 改名
变量和函数同名,return word2dict 这句会有问题吧? |
17
mixure 2019-11-29 15:39:29 +08:00 1
我想知道 V2EX 怎么不让代码发出来乱七八糟的。
--- from doctest import testmod def can_be_composed(word1,word2): """ >>> can_be_composed('lesson', 'professional') True >>> can_be_composed('lesson', 'longest') False """ word2=list(word2) try: [word2.remove(word) for word in word1] except ValueError: return False return True testmod() --- 我在 Ipython 里面 用 time 试了以下,似乎比 1 楼的还快一些 |
18
yucongo 2019-11-30 00:40:31 +08:00
楼上想法不错,一行实现,好像没办法 lambda 实现
def check1(word1, word2): list2 = [*word2]; return not any([*map(lambda x: list2.remove(x) if x in list2 else True, word1)]) check('lesson', 'responsible') # True check('lesson', 'longest') # False |