Python Checkio


今天偶尔从一个师兄那里看到了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
总之,听好玩的。这里只是写一个例子,推荐给大家。

评论关闭