2012-12-05 64 views
13

鉴于下列矢量更大的索引,查找元素大于x

a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 

我需要确定的“一”的元素是> =大于4时,这样的指数:

idx = [3, 4, 5, 6, 7, 8] 

在“IDX”的信息将被用于删除从另一个列表X的元素(X具有相同数量的元素的“一”):

del X[idx] #idx is used to delete these elements in X. But so far isn't working. 

I H听说numpy可能会有所帮助。有任何想法吗? 谢谢!

+0

循环是一个很好的开始。 – monkut

+0

您的'idx'示例是错误的,列表中只有** 9个元素**,因此** 9个索引0-8 **。 – Aesthete

+0

你的问题与自己有点矛盾。看起来你可能会混淆索引与元素(你的'idx'实际上是元素列表,而你正在询问索引列表)。也请告诉你之前你自己尝试了什么? – 0xc0de

回答

11

OK,我明白你的意思和Python的单线就足够了:

使用列表理解

[ j for (i,j) in zip(a,x) if i >= 4 ] 
# a will be the list compare to 4 
# x another list with same length 

Explanation: 
>>> a 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> x 
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j'] 

邮编函数会返回一个元组列表

>>> zip(a,x) 
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')] 

列表理解是一种快捷方式,用于在“in”之后循环列表中的元素,然后使用表达式评估元素,然后将结果返回给列表,还可以添加条件,以便返回

>>> [expression(element) for **element** in **list** if condition ] 

这段代码什么都不做,只是返回所有压缩的对。

>>> [(i,j) for (i,j) in zip(a,x)] 
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')] 

我们做的是它通过添加一个条件指定 “如果” 使用Itertools

>>> [ _ for _ in itertools.compress(d, map(lambda x: x>=4,a)) ] 
# a will be the list compare to 4 
# d another list with same length 

使用itertools.compress与布尔表达式

>>> [(i,j) for (i,j) in zip(a,x) if i >= 4] 
[(4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'j')] 

跟随Python中单行完成关闭此任务

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> d = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j'] # another list with same length 
>>> map(lambda x: x>=4, a) # this will return a boolean list 
[False, False, False, True, True, True, True, True, True] 


>>> import itertools 
>>> itertools.compress(d, map(lambda x: x>4, a)) # magic here ! 
<itertools.compress object at 0xa1a764c>  # compress will match pair from list a and the boolean list, if item in boolean list is true, then item in list a will be remain ,else will be dropped 
#below single line is enough to solve your problem 
>>> [ _ for _ in itertools.compress(d, map(lambda x: x>=4,a)) ] # iterate the result. 
['d', 'e', 'f', 'g', 'h', 'j'] 

itertools的解释。压缩,我认为这将是清楚的理解:

>>> [ _ for _ in itertools.compress([1,2,3,4,5],[False,True,True,False,True]) ] 
[2, 3, 5] 
+0

@OliverAmundsen这将是我的最终解决方案 –

+0

工作!谢谢@ShawnZhang。能否简要解释“使用列表理解”的逻辑? thx –

+0

@OliverAmundsen我已经更新了我的答案 –

20
>>> [i for i,v in enumerate(a) if v > 4] 
[4, 5, 6, 7, 8] 

enumerate返回在数组索引以及每个项目的值。因此,如果值v大于4,请在新阵列中包含索引i

或者您可以修改您的列表并排除4以上的所有值。使用过滤器内置函数

>>> a[:] = [x for x in a if x<=4] 
>>> a 
[1, 2, 3, 4] 
5
>>> import numpy as np 
>>> a = np.array(range(1,10)) 
>>> indices = [i for i,v in enumerate(a >= 4) if v] 
>>> indices 
[3, 4, 5, 6, 7, 8] 

>>> mask = a >= 4 
>>> mask 
array([False, False, False, True, True, True, True, True, True], dtype=boo 
l) 
>>> a[mask] 
array([4, 5, 6, 7, 8, 9]) 
>>> np.setdiff1d(a,a[mask]) 
array([1, 2, 3]) 
1

是细

>>>a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>>filter(lambda x : x < 4, a) 
[1, 2, 3] 

说明

过滤器(FUN,可迭代)

此表达式将遍历从可迭代所有元件并提供FUN功能作为参数,如果返回i真的,那么arugment将被添加到一个内部列表

拉姆达X:X> 4

这意味着一个匿名函数,将采取一个说法,如果大于4进行测试,并返回TRUE的假值

您的解决方案

,如果你试图删除大于4的所有元素,然后尝试打击

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> filter(lambda x: x<4 ,a) 
[1, 2, 3] 
+0

当您调用'del a [9]'时会发生什么? – Aesthete

+1

-1。您正在返回列表元素,而不是索引。虽然这适用于给定的列表,但它不是一个正确的答案。 – 0xc0de

+0

@Aesthete这里的长度是9,a [9]意味着list.if del a [9]的第10个元素,python会抛出一个索引错误 –

2

最简单的在我眼里是使用numpy的

X[np.array(a)>4]#X needs to be np.array as well 

说明: np.array一个转换到一个数组。

np.array(一)> 4给出具有所以只有其中a是大于4的元素被选择应保持

而X由布尔阵列过滤的所有元素一个bool阵列(和其余丢弃)