代码之家  ›  专栏  ›  技术社区  ›  MK.

选择满足某一谓词的随机值的方法

  •  2
  • MK.  · 技术社区  · 14 年前

    假设我有一个元素列表,我想从满足谓词的列表中随机选择一个元素。做这个的方法是什么?

    我现在做了一个理解,然后是 random.choice() 但这是不必要的效率低下:

    intlist = [1,2,3,4,5,6,7,8,9]
    evenlist = [ i for i in intlist if i % 2 == 0 ] 
    randomeven = random.choice(evenlist)
    

    谢谢!

    5 回复  |  直到 14 年前
        1
  •  2
  •   Benson    14 年前

    上面写的方法实际上是很好的惯用Python。如果我们分析算法,我们会发现它本质上是这样做的:

    1. 列出满足谓词的元素。(与n呈线性增长)
    2. 从列表中选择一个随机元素。(固定时间)

    唯一的另一种方法是随机选择一个元素,决定它是否满足谓词,如果不满足,则再次选择。这个算法有点复杂。在列表的90%满足谓词的情况下,这将比解决方案运行得更快。在只有10%的列表满足谓词的情况下,实际运行速度会慢得多,因为很有可能随机选择一个给定元素,并检查该元素是否满足谓词多次。现在你可以考虑记忆你的谓词,但是你仍然要选择很多随机数据。归根结底,除非您的解决方案特别不适合您的数据,否则请坚持使用它,因为它非常棒。就我个人而言,我会这样改写它:

    intlist = range(1,10)
    randomeven = random.choice([i for i in intlist if i % 2 == 0])
    

    这有点简洁,但它的运行方式与现有代码完全相同。

        2
  •  1
  •   phimuemue    14 年前

    我找不到某种函数 random.selectspecific(list, predicate) 在文档中,我将尝试如下操作:

    import random
    def selectspecific(l, predicate):
        result = random.choice(l)
        while (not predicate(result)):
            result = random.choice(l)
        return result
    
        3
  •  1
  •   Bertrand Marron    14 年前
    import random
    
    intlist = [1,2,3,4,5,6,7,8,9]
    randomeven = random.choice(filter(lambda x: x % 2 == 0, intlist))                                                                                                                                                         
    
        4
  •  0
  •   Austin Richardson    14 年前

    这是怎样的蟒蛇?

    from itertools import ifilterfalse
    from random import choice
    print choice([ i for i in ifilterfalse(lambda x: x%2, range(10)) ])
    
        5
  •  0
  •   tdedecko    14 年前

    如果您想封装更多的内容,您可以创建一个方法来处理选择,这将接受一个谓词方法。然后可以将此谓词方法用于 filter() .

    import random
    def selectSpecific(intlist, predicate):
      filteredList = filter(predicate, intlist)
      result = random.choice(filteredList)
      return result
    

    可以将谓词传递给 selectSpecific() 作为一个 lambda 或任何其他方法。例子:

    intlist = range(1,10)
    selectSpecific(intlist, lambda x: x % 2 == 0)
    
    def makeEven(n):
      if n % 2 == 0:
        return n
    
    selectSpecific(intlist, makeEven)