2012-07-08 372 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