2012-07-08 114 views
2

我有一个列表包含布尔值的列表子集的元素:的Python - 评估

my_list = [False, False, False, True, 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 

目前我在做这个:

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做到这一点?

+2

不要调用一个list,'list' ... – Ben 2012-07-08 09:57:15

+0

你的列表和由[true]或[false]定义的列表之间的交集是干什么的? – 2012-07-08 09:57:36

+1

由于'list'影响内建,所以将列表名称更改为'my_list' – jamylak 2012-07-08 09:59:11

回答

8
>>> 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 
+0

+1。我喜欢这个,因为它很好很清楚,除了变量名的大写'L' - 根据pep8,像参数这样的局部变量是'lowercase_with_caps'。 – 2012-07-08 10:01:51

+0

@Lattyware PEP8说:“当试图使用'l'时,请使用'L'。也请不要指定'lowercase_with_underscores'? – jamylak 2012-07-08 10:03:18

+0

'L'是一个在python中命名列表的约定吗? – armandino 2012-07-08 10:26:07

3

你可以这样做:

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

功能any返回true如果给定的迭代中包含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 
+0

这不会像提问者想要的那样完美 - 如果你看到他的例子,他想要结束边界加一个。 – 2012-07-08 09:59:01

+0

@Lattyware:谢谢,我已经添加了+1来提供期望的结果。 – 2012-07-08 10:00:07

+0

@Simeon太好了,谢谢你的解释。 – armandino 2012-07-08 10:29:20

1

你的代码有一个错误。

另外还有一点说,有两个硬东西 计算机科学这个变化:缓存失效,事物命名,并关闭的情况的一个 错误。

你列出的例子表明,“端”为包容(0,0)(5,5)两个长度的选择子列表1.

range(0,0)range(5,5)对待第二“端”为独家range(0,0)range(5,5)是索引的空列表。

您需要在范围调用的'结束'索引中加1以使代码按预期工作。

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

+2

这不是一个答案 - 问题是如果有更好的方法,不要用他现有的代码来解释问题。这更适合作为评论。 – 2012-07-08 10:01:04

+0

@Lattyware - 真实,这就是为什么我并发您的评论并附上我的itertools建议。干杯。 – 2012-07-08 10:04:05

+0

@克里斯谢谢!接得好。我失去了它简化了这个例子。 – armandino 2012-07-08 10:17:38

0

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

import numpy as np 

然后你的函数看起来是这样的:

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

你的意思是_tuple_?而且,你不能只写'return l [tupel [0]:tupel [1]]。any()'? – Ben 2012-07-08 10:09:38

+0

或更简单的'retrun l [tupel [0]:tupel [1]]。any()' – MaxPowers 2012-07-08 10:10:43

+1

哦,是的,我做的Tupel只是德语拼写。 – MaxPowers 2012-07-08 10:12:05

2

的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]) 
+0

+1我不知道你可以使用像这样的函数参数名称 – jamylak 2012-07-08 10:24:24

+2

为什么使用'lambda'?这看起来更像一个“def”。我不确定这是否是比我的解决方案更好的风格......看起来很不错。 – jamylak 2012-07-08 10:26:00

+0

@SimeonVisser我还没有意识到这一点,所以我想这意味着我的方式是被接受的方式。 – jamylak 2012-07-08 10:30:17