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

时间:2010-05-14 16:18:18

标签: python

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

我目前正在进行理解,然后是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 个答案:

答案 0 :(得分:2)

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

  1. 制作满足谓词的元素列表。 (与n线性增长)
  2. 从该列表中选择一个随机元素。 (恒定时间)
  3. 唯一的另一种方法是随机选择一个元素,判断它是否满足谓词,如果不满足则再次选择。这个算法有点复杂。在90%的列表满足谓词的情况下,这将比您的解决方案运行得快得多。在只有10%的列表满足谓词的情况下,它实际上运行得慢得多,因为很有可能它会随机选择给定的元素并检查谓词是否多次满足该元素。现在你可以考虑记住你的谓词,但你仍然会选择很多随机数据。它归结为:除非你的解决方案特别适合你的数据,坚持下去,因为它很棒。就个人而言,我会像这样重写:

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

    这更简洁,但它将与您现有的代码完全相同。

答案 1 :(得分:1)

我在文档中找不到random.selectspecific(list, predicate)的函数类型,所以我会尝试类似以下内容:

import random
def selectspecific(l, predicate):
    result = random.choice(l)
    while (not predicate(result)):
        result = random.choice(l)
    return result

答案 2 :(得分:1)

import random

intlist = [1,2,3,4,5,6,7,8,9]
randomeven = random.choice(filter(lambda x: x % 2 == 0, intlist))                                                                                                                                                         

答案 3 :(得分:0)

这是多么pythonic?

from itertools import ifilterfalse
from random import choice
print choice([ i for i in ifilterfalse(lambda x: x%2, range(10)) ])

答案 4 :(得分:0)

如果你想封装更多,你可以创建一个方法来处理选择,这将接受谓词方法。然后,您可以将此谓词方法与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)
相关问题