【问题标题】:Python - evaluate elements of a list subsetPython - 评估列表子集的元素
【发布时间】:2012-07-08 09:54:44
【问题描述】:

我有一个包含布尔值的列表:

my_list = [False, False, False, True, True, True]

我想评估对于具有 (start, end) 索引的给定元组,列表是否包含 True 值,例如

contains_true(my_list, (0,0)) => False
contains_true(my_list, (0,2)) => False
contains_true(my_list, (0,3)) => True
contains_true(my_list, (3,5)) => True
contains_true(my_list, (5,5)) => True

目前我正在这样做:

def contains_true(my_list, indexes_tuple):
    start = indexes_tuple[0]
    end = indexes_tuple[1] + 1
    indexes = range(start, end)

    for i in indexes:
        if my_list[i]:
            return True
    return False

有没有更好的方法在 Python 中做到这一点?

【问题讨论】:

  • 你的列表和由 [true] 或 [false] 定义的列表之间的交集怎么办?
  • 将列表名称更改为 my_list,因为 list 隐藏了内置函数
  • 我建议您默认使用半开范围。下面的答案使用[start, end+1] 来得到你的答案,但如果你的元组(0,3) 意味着包含元素0、1 和2,那么答案会更容易。 Some arguments are here.

标签: python list python-2.7


【解决方案1】:
>>> my_list = [False, False, False, True, True, True]
>>> def contains_true(seq, bounds):
        start, end = bounds
        return any(seq[start:end+1])

>>> contains_true(my_list, (0,0))
False
>>> contains_true(my_list, (0,2))
False
>>> contains_true(my_list, (0,3))
True
>>> contains_true(my_list, (3,5))
True
>>> contains_true(my_list, (5,5))
True

【讨论】:

  • +1。我喜欢这个,因为它很好,很清晰,除了变量名的大写 L - 根据 pep8,像参数这样的局部变量是 lowercase_with_caps
  • @Lattyware PEP8 说When tempted to use 'l', use 'L' instead. 你不是说lowercase_with_underscores吗?
  • L是python中命名列表的约定吗?
  • @armandino 我喜欢这样想,但它没有写在任何地方。更多人使用lstdata 之类的东西
  • @jamylak 哇,不知道我是如何获得lowercase_with_caps 的——你说得对,这是推荐的。也就是说,我会选择seq,因为这是很多内置函数使用的。
【解决方案2】:

你可以这样做:

def contains_true(data, indices):
     return any(data[indices[0]:indices[1] + 1])

如果给定的可迭代对象包含True,则函数any 返回True。上面的函数对列表进行切片,如果切片包含至少一个 True 值,则返回 True。这给出了您的预期结果:

contains_true(my_list, (0,0)) => False
contains_true(my_list, (0,2)) => False
contains_true(my_list, (0,3)) => True
contains_true(my_list, (3,5)) => True
contains_true(my_list, (5,5)) => True

【讨论】:

  • 这不会像提问者想要的那样 - 如果你看到他的例子,他想要结束边界加一。
  • @Lattyware:谢谢,我添加了 +1 以提供所需的结果。
【解决方案3】:

Python 2:

contains_true = lambda L, (start, end): any(L[start:end+1])

或者在 Python 2 和 3 中:

contains_true = lambda L, start_end: any(L[start_end[0]:start_end[1]+1])

【讨论】:

  • +1 我不知道你可以使用这样的函数参数名称
  • 为什么使用lambda?作为def,这看起来会好很多。我不确定这是否比我的解决方案更好……看起来不错。
  • @SimeonVisser 我也没有意识到这一点,所以我想这意味着我的方式是公认的方式。
  • @Simeon Visser :对不起,我忘记了。我添加了一个 Python 3 版本。
【解决方案4】:

您的代码有一个错误。

还有一个变体,说有两个困难的事情 在计算机科学中:缓存失效、命名事物和逐一 错误。

您的示例列表显示“结束”是包含(0,0)(5,5) 都选择长度为 1 的子列表。

但是range(0,0)range(5,5) 将第二个“结束”视为独占,而range(0,0)range(5,5) 是空的索引列表。

您需要将 1 添加到范围调用的“结束”索引,以使您的代码按预期工作。

有没有更好的方法?您可以使用import itertoolsitertools.islice 获取子列表并将其传递给any 函数。这对你更好吗?

【讨论】:

  • 这不是答案——问题是是否有更好的方法,而不是用他现有的代码来解释问题。这更适合作为评论。
  • @Lattyware - 是的,这就是为什么我将我的 itertools 建议与您的评论同时附加。干杯。
  • @Chris 谢谢!接得好。我把它简化了这个例子。
【解决方案5】:

你的 List 应该是一个 numpy 数组,所以:

import numpy as np

那么你的函数可能如下所示:

def contains_true(list,tupel):
    if l[tupel[0]:tupel[1]].any()==True: 
        return True
    else: 
        return False

【讨论】:

  • 你的意思是元组吗?而且,你不能写return l[tupel[0]:tupel[1]].any()吗?
  • 或更简单的retrun l[tupel[0]:tupel[1]].any()
  • 不要使用 listtuple/tupel 作为名称,因为您正在隐藏插件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
相关资源
最近更新 更多