获取最低计数*的列表中的元素

时间:2016-11-03 04:54:04

标签: python list lambda count min

我有一个列表,我想找到具有最低数量' *'的元素。

mylist = ['12*3','12345**6','11234']

所以这个小测试的答案是' 11234'

这种方法有效,但速度很慢(我正在处理大量的基因组数据:

sorted(mylist, key = lambda x: x.count('*'))[0]

这不那么雄辩,但有效:

values = map(lambda x: x.count('*'), mylist)
print mylist[values.index(min(values))]

有更好的方法吗? 我试图做一个schwartzian变换,但无法弄清楚。

2 个答案:

答案 0 :(得分:7)

您可以将minkey参数一起使用:

>>> mylist = ['12*3','12345**6','11234']
>>> min(mylist, key=lambda x: x.count('*'))
'11234'

key是一个函数,在iterable上的每个项目上调用,以与sorted中相同的方式指定排序。

上述方法将导致 O(n)时间复杂度,其中排序为 O(n log n)

更新:如果您的字符串非常长,那么您可以在循环中计算*的出现次数,并在count与当前最小值相同时拒绝该字符串。如果找到出现0次的字符串,您也可以终止搜索:

def find(l):
    min_item = None
    min_val = float('inf')

    for x in l:
        current = 0
        for c in x:
            current += (c == '*')
            if current >= min_val:
                break
        else:
            # Found new minimum, update
            min_item = x
            min_val = current

        # Can't get lower than 0
        if min_val == 0:
            break

    return min_item

print(find(['12*3','11234', '12345**6', '1'])) # '11234'

答案 1 :(得分:1)

您可以通过为key而不是lambda创建单独的函数来进一步提高性能,因为 lambda函数很慢。例如:

def get_asterisk_count(my_string):
    return my_string.count('*')

mylist = ['12*3','12345**6','11234']
min(mylist, key=get_asterisk_count)

以下是timeit统计信息:

  • 使用lambda功能:1.25 usec

    mquadri$ python -m "timeit" -s "mylist = ['12*3','12345**6','11234']" "min(mylist, key=lambda x: x.count('*'))"
    1000000 loops, best of 3: 1.25 usec per loop
    
  • 使用单独的功能:1.19 usec

    mquadri$ python -m "timeit" -s "mylist = ['12*3','12345**6','11234']" "def get_asterisk_count(my_string): return my_string.count('*')" "min(mylist, key=get_asterisk_count)"
    1000000 loops, best of 3: 1.19 usec per loop