【问题标题】:How to check if elements in list 'a' meet conditions in list 'b'?如何检查列表'a'中的元素是否满足列表'b'中的条件?
【发布时间】:2018-05-09 17:09:31
【问题描述】:

我有一个数字列表

a = [3, 6, 20, 24, 36, 92, 130]

以及条件的列表:

b = ["2", "5", "20", "range(50,100)", ">120"]

我想检查'a'中的一个数字是否满足'b'中的条件之一,如果是,将这些数字放入列表'c'中

以上情况:

c = [20, 92, 130]

我创建了这段代码似乎可以做我想做的事:

c = []
for x in a:
    for y in b:
        if "range" in y:
            rangelist = list(eval(y))
            if x in rangelist:
                c.append(x)
        elif ">" in y or "<" in y:
            if eval(str(x) + y):
                c.append(x)
        else:
            if x == eval(y):
                c.append(x)

但是我的列表“a”可能非常大。
难道没有更简单快捷的方式来获得我想要的东西吗?

【问题讨论】:

  • 为什么要在条件中保存字符串而不是整数,这会让事情变得更容易。
  • 你能把b改成=20in range(50,100)这样的有效条件吗?
  • 将函数放在b 列表中似乎更简洁,而不是进行一堆乱七八糟的字符串操作和eval
  • lambda x: x &gt; 120lambda x: 50 &lt;= x &lt; 100 之类的东西。
  • 这是在 Haskell 中的一个有趣的练习,因为它涉及定义一个 a -&gt; [(a -&gt; b)] -&gt; [b] 类型的反向映射(这可能在 Haskell 标准库中,但我找不到它)。 See my solution here

标签: python python-3.x list list-comprehension


【解决方案1】:

根据@user2357112 的建议,您可以为所有条件创建一个函数列表,然后将每个数字传递给每个函数,以确定该数字是否满足任何条件。

In [1]: a = [3, 6, 20, 24, 36, 92, 130]

In [2]: conditions = [lambda x:x==2, lambda x:x==5, lambda x:x==20, lambda x: x in range(50, 100), lambda x: x > 120]  # List of lambda functions

In [3]: output = list()

In [4]: for number in a:
   ...:     if any(func(number) for func in conditions): # Check if the number satisfies any of the given conditions by passing the number as an argument to each function
   ...:         output.append(number)         

In [5]: output
Out[5]: [20, 92, 130]

【讨论】:

  • 肯定更喜欢这个解决方案,喜欢如何创造性地使用 lambda。
  • 非常好的解决方案,但是如何将列表“b”更改为 lambda 条件?
  • @Reman 我已将列表“b”中的所有条件转换为 lambda 函数,并将它们存储在列表“条件”中。
  • @GaneshTata,是的,我已经看到了,但我没有可能在我的列表“b”中包含 lambda 函数。我有一个有问题的列表'b'。我必须调整它们,包括 lambda 函数。使用列表理解?像这样conditions = ["x:x==" + a if a.isdigit() elif "x: x in " + a if "range" in a else "a: a " + a for a in b]
  • 找到它:["x:x==" + a if a.isdigit() else "x: x in " + a if "range" in a else "a: a " + a for a in b]
【解决方案2】:

假设您可以更改 b 以保持有效条件(当与来自 a 的元素连接时),如上面的 cmets 中所述:

b = ["==2", "==5", "==20", "in range(50,100)", ">120"]

您可以使用这些条件连接a 的每个元素,并使用eval 检查它的计算结果是True 还是False。当然,这可以在列表推导中完成:

result = [i for i in a if any(eval(str(i) + x) for x in b)]

【讨论】:

  • Tnx,如果你拿a = [3, 6, 20, 24, 36, 92, 130, 180, 182, 190]b = ['==2', 'in range(150,200)', '&lt;120', '180']输出是错误的
  • 180 是一个数字,而不是一个条件。该程序连接两个字符串,Python 将所有值解释为True。您可以通过print(not(3180)) 进行检查。
  • 如果我使用上面的列表.. '130' 是结果。
【解决方案3】:

你想要简单、pythonic和容易掌握的忘记上面的那些

a = [3, 6, 20, 24, 36, 92, 130]
[i for i in a if i==2 or i==5 or i==20 or i>120 or 50<=i<=100 ]

【讨论】:

    【解决方案4】:

    根据之前的答案,我认为可能还有 2 种方法。

    #1
    numbers = [3, 6, 20, 24, 36, 92, 130]
    conditions = [
        lambda n: n == 2,
        lambda n: n == 5,
        lambda n: n == 20,
        lambda n: n in range(50, 100),
        lambda n: n > 120,
    ]
    result = [num for num in numbers for condition in conditions if condition(num)]
    
    #2
    condition = lambda n: n in {2, 5, 20} or 50 <= n <= 100 or n > 120
    result = list(filter(condition, numbers))
    

    对于一个非常大的列表,您应该使用示例 #2,因为它更节省内存并且时间复杂度是线性的,而不是 #1 中的二次方

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      • 2023-03-29
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      相关资源
      最近更新 更多