【问题标题】:Get element in list with lowest count of *获取列表中具有*数最少的元素
【发布时间】:2016-11-03 04:54:03
【问题描述】:

我有一个列表,我想找到“*”计数最少的元素。

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 转换,但无法弄清楚。

【问题讨论】:

    标签: python list lambda count min


    【解决方案1】:

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

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

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

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

    更新:如果您的字符串真的很长,那么您可以在循环中计算* 的出现次数,并在计数与当前最小值相同时立即拒绝该字符串。如果找到出现次数为 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'
    

    【讨论】:

      【解决方案2】:

      您可以通过为 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 微秒

        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
        

      【讨论】:

      • 我认为您的时间差异并不明显。当然不足以支持“lambda 函数很慢”的说法,或者 - 更慷慨地 - slower。当我多次运行相同的 sn-ps 时,有时命名函数会提前出现,有时 lambda 会提前出现。这让我相信这些差异纯粹是噪音和/或一些混杂因素。 AFAIK,在 CPython 中,lambdadef 函数的实现没有真正的区别。我看不出有任何理由说明 lambda 的执行会比等效的命名函数慢。
      猜你喜欢
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 2013-09-28
      • 2022-10-30
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 2018-02-12
      相关资源
      最近更新 更多