今天偶尔从一个师兄那里看到了checkio,感觉很好玩。
我看到的第一个题是要求写一个函数,接收一个数组,然后返回其中的重复元素,而且元素的顺序不能发生变化。换句话说,就是去掉其中不含重复的元素。比如:
checkio([1,2,3,1,3])==[1,3,1,3],"1st example"
checkio([1,2,3,4,5])==[], "2nd example"
checkio([5,5,5,5,5])==[5,5,5,5,5],"3rd example"
checkio([10,9,10,10,9,8])==[10,9,10,10,9],"4th example"
我首先想到的是用hash之类的判断重复的方法,后来想毕竟是python应该有好多现成的方法,我想到了list.count()(L.count(value) -> integer -- return number of occurrences of value in L.),鉴于前段时间刚和同学讨论了python的奇葩小特性中的列表解析。我写出了如下的代码:
def checkio(data): return [e for e in data if data.count(e) > 1]
看了下上面最火的答案是这样的,只有一行:
checkio=lambda d:[x for x in d if d.count(x)>1]
传说中效率最高的答案是这样的:
def checkio(data): from collections import Counter nonunique = Counter(data) - Counter(set(data)) return [x for x in data if x in nonunique]
上面用了collections中的一个Count()方法,生成一个Count对象,其中存储着数组转化成的一个字典,字典的key是数组元素,字典的value是元素在数组中出现的次数,而且两个Count对象相减的时候,会将对应key的value值相减,然后去掉其中value非正的键值对。上面的set方法的作用是Build an unordered collection of unique elements. 这样,就不难理解上面的代码了。
下面是一个求列表元素的中位数的题目,我的代码如下:
def checkio(data): l = len(data) s = sorted(data) if l % 2 == 0: return (s[l/2]+s[l/2-1])/2.0 else: return s[l/2]
上面比较火的代码巧妙的利用python中列表可以从后往前索引取值的特性,写出了如下代码:
def checkio(data): off = len(data) / 2 data.sort() med = data[off] + data[-(off + 1)] return med / 2.0
总之,听好玩的。这里只是写一个例子,推荐给大家。
Python Checkio