2012-12-05 39 views
13

Với vector sau,Tìm các chỉ số của các nguyên tố lớn hơn x

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

tôi cần phải xác định các chỉ số của "a" mà yếu tố này là> = hơn 4, như thế này:

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

Thông báo thông tin trong "idx" sẽ được sử dụng để xóa các phần tử từ một danh sách X (X có cùng một số yếu tố "a"):

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

tôi h có thể giúp đỡ. Bất kỳ ý tưởng? Cảm ơn!

+0

vòng lặp là một nơi tốt để bắt đầu. – monkut

+0

Ví dụ 'idx' của bạn sai, chỉ có ** 9 phần tử ** trong danh sách và do đó ** 9 chỉ mục, 0-8 **. – Aesthete

+0

Câu hỏi của bạn hơi mâu thuẫn với chính nó. Có vẻ như bạn có thể đã nhầm lẫn các chỉ mục với các phần tử (thực tế là 'idx' của bạn là danh sách các phần tử và bạn đang yêu cầu danh sách các chỉ mục). Ngoài ra xin vui lòng cho biết những gì bạn đã thử một mình trước khi yêu cầu? – 0xc0de

Trả lời

11

OK, tôi hiểu những gì bạn có ý nghĩa và một dòng đơn của Python sẽ đủ:

sử dụng danh sách hiểu

[ 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'] 

chức năng Zip sẽ trả về một danh sách các hàng

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

List comprehension là một phím tắt để lặp thành phần trong danh sách sau "in" và đánh giá phần tử với biểu thức, sau đó trả về kết quả cho danh sách, bạn cũng có thể thêm điều kiện mà kết quả bạn muốn trả về

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

Mã này không có gì ngoài việc trả lại tất cả các cặp đã được nén lên.

>>> [(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')] 

Những gì chúng ta làm là thêm một điều kiện trên nó bằng cách chỉ định "nếu" làm theo bởi một biểu thức boolean

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

sử dụng 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 

Sử dụng itertools.compress với dòng đơn bằng Python để hoàn thành việc này

>>> 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'] 

Giải thích cho công cụ lặp.nén, tôi nghĩ rằng điều này sẽ được rõ ràng cho sự hiểu biết của bạn:

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

@OliverAmundsen đây sẽ là giải pháp cuối cùng của tôi –

+0

đã hoạt động! Cảm ơn @ShawnZhang. Có thể giải thích ngắn gọn logic của "sử dụng danh sách hiểu"? thx –

+0

@OliverAmundsen Tôi đã cập nhật câu trả lời của mình –

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

enumerate trả về chỉ mục và giá trị của từng mục trong một mảng. Vì vậy, nếu giá trị v lớn hơn 4, hãy bao gồm chỉ mục i trong mảng mới.

Hoặc bạn chỉ có thể sửa đổi danh sách của mình tại chỗ và loại trừ tất cả các giá trị trên 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

sử dụng bộ lọc tích hợp chức năng là tốt

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

Giải thích

lọc (FUN, Iterable)

biểu thức này sẽ lặp tất cả các phần tử từ Iterable và cung cấp chức năng FUN làm đối số, nếu trả lại i s True, thì arugment sẽ được thêm vào sau một danh sách nội

lambda x: x> 4

điều này có nghĩa là một chức năng vô danh mà sẽ mất một cuộc tranh luận và thử nghiệm nó nếu lớn hơn 4 và trở Đúng False giá trị

giải pháp của bạn

nếu bạn đang cố gắng để xóa tất cả các yếu tố lớn hơn 4, sau đó thử đòn

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

Và điều gì sẽ xảy ra khi bạn gọi 'del a [9]'? – Aesthete

+1

-1. Bạn đang trả về các phần tử danh sách, không phải các chỉ mục. Mặc dù điều này làm việc cho danh sách nhất định nhưng nó không phải là một câu trả lời đúng. – 0xc0de

+0

@Độ dài vượt trội của một ở đây là 9, [9] có nghĩa là yếu tố thứ 10 của danh sách.if del a [9], python sẽ ném một lỗi chỉ mục –

2

Cách đơn giản nhất trong mắt tôi sẽ được sử dụng NumPy

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

Giải thích: np.array chuyển đổi một đến một mảng.

np.array (a)> 4 đưa ra một mảng bool với tất cả các yếu tố đó phải được giữ

Và X được lọc bởi các mảng bool vì vậy chỉ những yếu tố mà một lớn hơn 4 được lựa chọn (và phần còn lại bị loại bỏ)

Các vấn đề liên quan