大多数pythonic方式随机选择具有条件的列表中的元素

时间:2017-05-29 14:23:54

标签: python python-3.x random conditional-statements

我有两个清单:

list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = [1, 4, 5]

我想从list1中选择一个元素,但它不应属于list2

我有一个使用while循环的解决方案,但我希望有一个更加pythonic和优雅的单线。

5 个答案:

答案 0 :(得分:8)

如果您的元素是唯一的,您可以使用设置差异。 (将list1转换为set并从list2中删除元素)。然后画一个随机样本。

random.choice(list(set(list1).difference(list2)))

答案 1 :(得分:1)

[item for item in list1 if not in list2]

为了使它更快一些(因为set in set in faster in list):

list2_items = set(list2)
[item for item in list1 if not in list2_items]

或使用过滤器功能(您将在Python3中获得生成器对象

filter(lambda item: item not in list2, list1)

将list2转换为set也会加速过滤。

了解有关list comprehensions的更多信息。

更新:似乎我错过了关于一个随机值的观点。好吧,你仍然可以使用列表推导,但是如前所述使用random.choice

import random
random.choice([item for item in list1 if not in list2_items])

它将过滤选择,然后随机获得一个。 @zeehio响应看起来更好的解决方案。

答案 2 :(得分:0)

import random
import itertools

next(item for item in (random.choice(list1) for _ in itertools.count()) if item not in list2)

相当于:

while True:
    item = random.choice(list1)
    if item not in list2:
        break

答案 3 :(得分:0)

您可能希望像set一样使用list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2 = [1, 4, 5] import random print(random.choice([x for x in set(list1).difference(list2)])) # kudos @chepner

set(list1) - set(list2)

这样我们可以从list1中的list2:元素中随机抽取,而不是list1中的元素。这种方法也可以很好地扩展到列表1& 2变大。

正如@MSeifert所注意到的,setlist1的转换将删除list1中可能存在的任何重复元素,从而改变概率。如果print(random.choice([x for x in list1 if x not in list2])) 在一般情况下可能包含重复元素,则可能需要执行此操作:

  string source = "Esmael20170101one";

  var match = Regex.Match(source, 
    @"^(?<name>[A-Za-z]+)(?<code>[0-9]+)(?<suffix>[A-Za-z]{3})$");

  string name = match.Groups["name"].Value;
  string code = match.Groups["code"].Value;
  string suffix = match.Groups["suffix"].Value;

答案 4 :(得分:-1)

不导入随机库:

private void dg_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    DataGridRow row = sender as DataGridRow;
    dg.SelectedItem = row.DataContext;
}

在pop()里面你可以给出你想要选择的元素的索引,它会弹出那个元素 示例:用于选择索引1的列表(来自新列表),print((list(set(list1) - set(list2))).pop())

此处((list(set(list1) - set(list2))).pop(1))代码将创建一个新列表,其中仅包含第一个列表中不存在于第二个列表中的项目的列表,