从满足标准的列表中提取随机值?python

从满足标准的列表中提取随机值?python,python,random,Python,Random,是否可以使用随机模块从列表中提取字符串,但前提是字符串的长度大于x 例如: list_of_strings = ['Hello', 'Hello1' 'Hello2'] 如果设置x=5并调用random.choice()则代码将仅在list\u字符串[1]和list\u字符串[2]之间进行“选择” 我意识到您可以创建第二个列表,其中只包含len>x的值,但我想知道,如果不执行此步骤,是否可以执行此操作。您可以执行以下操作: random.choice([i for i in list_of_s

是否可以使用随机模块从列表中提取字符串,但前提是字符串的长度大于x

例如:

list_of_strings = ['Hello', 'Hello1' 'Hello2']
如果设置
x=5
并调用
random.choice()
则代码将仅在
list\u字符串[1]
list\u字符串[2]
之间进行“选择”

我意识到您可以创建第二个列表,其中只包含
len>x的值,但我想知道,如果不执行此步骤,是否可以执行此操作。

您可以执行以下操作:

random.choice([i for i in list_of_strings if len(i) > x])
或者你可以这样做:

while True:
    choice = random.choice(list_of_strings)
    if len(choice) > x:
        return choice
您应该首先检查列表中是否有长于x的字符串,否则代码将永远不会结束


另一种可能的解决方案是使用储层采样,它还有一个额外的好处,即运行时间有限。

另一种不创建额外列表的解决方案:

from itertools import islice
from random import randrange

def choose_if(f, s):
  return next(islice(filter(f, s), randrange(sum(map(f, s))), None))

choose_if(lambda x: len(x) > 5, list_of_strings)
事实证明,它几乎比Christian的解决方案慢两倍。这是因为它在
s
上迭代两次,对每个元素应用
f
。它的成本足以超过不创建第二个列表的好处

另一方面,Francisco的解决方案可能比这快10到100倍,因为它应用
f
的次数仅与未能选择合适元素的次数相同。以下是该函数的完整版本:

from random import choice

def choose_if(f, s):
  if any(filter(f, s)):
    while True:
      x = choice(s)
      if f(x): return x

请记住,当少数(小于1%)元素满足条件时,情况会变得更糟。当5000中只有1个元素是好的时,它比使用列表理解慢5倍。

“我意识到你可以制作第二个列表,其中只包含len>x的值,但我想知道如果没有此步骤,是否可能。”“我意识到您可以制作第二个列表,其中只包含len>x的值,但我想知道,如果不执行此步骤,是否可行。“如果满足条件的元素不多,那么速度也会很慢。查看我的答案了解更多详细信息。看,使用循环是可能的,但使用理解可能更好。不太确定,但理解也会创建另一个列表。
from random import choice

def choose_if(f, s):
  if any(filter(f, s)):
    while True:
      x = choice(s)
      if f(x): return x