博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
欣赏一个简洁利落的解法
阅读量:4936 次
发布时间:2019-06-11

本文共 1862 字,大约阅读时间需要 6 分钟。

今天欣赏一个包含众多知识点的解法。是这样的:

给定两个字符串s1和s2,统计它们各自包含的各个小写字母的个数,然后互相比较。如果对某个字母,s1中出现的次数多,就打印“1:aaaa” (表示字母a在s1中出现了4次);如果s2中出现的次数多,就打印“2:aaaa”;如果次数相同,就打印“=:aaaa”。最后输出整个的比较结果,输出时先按次数排序,再按1-2-=排序,最后按字母排序。

举个例子:

s1 = "my&friend&Paul has heavy hats! &"

s2 = "my friend John has many many friends &"

mix(s1, s2) --> "2:nnnnn/1:aaaa/1:hhh/2:mmm/2:yyy/2:dd/2:ff/2:ii/2:rr/=:ee/=:ss"

分析:

这个题目其实挺简单的。统计字母个数?遍历+字典轻松搞定。比较两个字典?逐个即可。最后输出的先按...排序,再按...排序,最后按...排序?有点麻烦,不过用itemgetter也可以做到。

但是,这里我想请大家一起欣赏一下这个,非常利落:

from collections import Counterdef mix(s1, s2):    c1 = Counter(filter(str.islower, s1))    c2 = Counter(filter(str.islower, s2))    res = []    for c in set(c1.keys() + c2.keys()):        n1, n2 = c1.get(c, 0), c2.get(c, 0)        if n1 > 1 or n2 > 1:            res.append(('1', c, n1) if n1 > n2 else                ('2', c, n2) if n2 > n1 else ('=', c, n1))    res = ['{}:{}'.format(i, c * n) for i, c, n in res]    return '/'.join(sorted(res, key=lambda s: (-len(s), s)))

 解析:

1. filter:

filter(function, sequence)对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)返回。

对于s1="my&friend&Paul has heavy hats! &",filter(str.islower, s1)为取出其中的所有小写字母:

'myfriendaulhasheavyhats'

 

2. Counter:

Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。

Counter(filter(str.islower, s1))的结果为:

{'a': 4, 'h': 3, 'e': 2, 's': 2, 'y': 2, 'd': 1, 'f': 1, 'i': 1, 'm': 1, 'l': 1, 'n': 1, 'r': 1, 'u': 1, 't': 1, 'v': 1}

 

3. 合并遍历2个字典:

for c in set(c1.keys() + c2.keys()):

 

4. 根据tuple合成一个字符串列表:

res = ['{}:{}'.format(i, c * n) for i, c, n in res]

 

5. 多重排序:

对于['2:aa', '2:ee', '2:dd', '=:gg', '1:ii', '1:ooo', '=:nnn', '2:sss', '1:uuu']这样一个列表,如何先按照次数(字符串长度)、再按照1-2-=、最后按照字母排序?

用lambda指定sorted的key参数:

sorted(res, key=lambda s: (-len(s), s))

相当于先按照s的长度从大到小(-len(s))排序,再按照s的字母数字排序(1>2>=, 1:aa>1:bb)。

 

转载于:https://www.cnblogs.com/netoops/p/6923253.html

你可能感兴趣的文章