Python List Comprehension을 사용하여 조건에 따라 요소의 인덱스 찾기
다음 Python 코드는 Matlab 배경에서 올 때 매우 긴 것으로 보입니다.
>>> a = [1, 2, 3, 1, 2, 3]
>>> [index for index,value in enumerate(a) if value > 2]
[2, 5]
Matlab에서 다음과 같이 작성할 수 있습니다.
>> a = [1, 2, 3, 1, 2, 3];
>> find(a>2)
ans =
3 6
이것을 파이썬으로 작성하는 짧은 방법이 있습니까, 아니면 긴 버전을 고수합니까?
파이썬 구문의 근거에 대한 모든 제안과 설명에 감사드립니다.
numpy 웹 사이트에서 다음을 찾은 후 내가 좋아하는 솔루션을 찾은 것 같습니다.
http://docs.scipy.org/doc/numpy/user/basics.indexing.html#boolean-or-mask-index-arrays
해당 웹 사이트의 정보를 위의 문제에 적용하면 다음이 제공됩니다.
>>> from numpy import array
>>> a = array([1, 2, 3, 1, 2, 3])
>>> b = a>2
array([False, False, True, False, False, True], dtype=bool)
>>> r = array(range(len(b)))
>>> r(b)
[2, 5]
그러면 다음이 작동합니다 (하지만 테스트 할 Python 인터프리터가 없습니다).
class my_array(numpy.array):
def find(self, b):
r = array(range(len(b)))
return r(b)
>>> a = my_array([1, 2, 3, 1, 2, 3])
>>> a.find(a>2)
[2, 5]
Python에서는이를 위해 인덱스를 전혀 사용하지 않고 값만 처리합니다
[value for value in a if value > 2]
. 일반적으로 인덱스를 다루는 것은 최선의 방법을 사용하지 않는다는 것을 의미합니다.Matlab과 유사한 API 가 필요한 경우 Matlab에서 크게 영감을받은 Python의 다차원 배열 및 수치 수학 패키지 인 numpy를 사용 합니다. 목록 대신 numpy 배열을 사용합니다.
>>> import numpy >>> a = numpy.array([1, 2, 3, 1, 2, 3]) >>> a array([1, 2, 3, 1, 2, 3]) >>> numpy.where(a > 2) (array([2, 5]),) >>> a > 2 array([False, False, True, False, False, True], dtype=bool) >>> a[numpy.where(a > 2)] array([3, 3]) >>> a[a > 2] array([3, 3])
또 다른 방법:
>>> [i for i in range(len(a)) if a[i] > 2]
[2, 5]
일반적으로 는 준비된 기능이지만 목록 이해는 일반적이므로 매우 강력한 솔루션 이라는 점 을find
기억하십시오 . find
파이썬 으로 함수 를 작성하고 나중에 원하는대로 사용 하는 것을 방해하는 것은 없습니다 . 즉 :
>>> def find_indices(lst, condition):
... return [i for i, elem in enumerate(lst) if condition(elem)]
...
>>> find_indices(a, lambda e: e > 2)
[2, 5]
Note that I'm using lists here to mimic Matlab. It would be more Pythonic to use generators and iterators.
For me it works well:
>>> import numpy as np
>>> a = np.array([1, 2, 3, 1, 2, 3])
>>> np.where(a > 2)[0]
[2 5]
Maybe another question is, "what are you going to do with those indices once you get them?" If you are going to use them to create another list, then in Python, they are an unnecessary middle step. If you want all the values that match a given condition, just use the builtin filter:
matchingVals = filter(lambda x : x>2, a)
Or write your own list comprhension:
matchingVals = [x for x in a if x > 2]
If you want to remove them from the list, then the Pythonic way is not to necessarily remove from the list, but write a list comprehension as if you were creating a new list, and assigning back in-place using the listvar[:]
on the left-hand-side:
a[:] = [x for x in a if x <= 2]
Matlab supplies find
because its array-centric model works by selecting items using their array indices. You can do this in Python, certainly, but the more Pythonic way is using iterators and generators, as already mentioned by @EliBendersky.
Even if it's a late answer: I think this is still a very good question and IMHO Python (without additional libraries or toolkits like numpy) is still lacking a convenient method to access the indices of list elements according to a manually defined filter.
You could manually define a function, which provides that functionality:
def indices(list, filtr=lambda x: bool(x)):
return [i for i,x in enumerate(list) if filtr(x)]
print(indices([1,0,3,5,1], lambda x: x==1))
Yields: [0, 4]
In my imagination the perfect way would be making a child class of list and adding the indices function as class method. In this way only the filter method would be needed:
class MyList(list):
def __init__(self, *args):
list.__init__(self, *args)
def indices(self, filtr=lambda x: bool(x)):
return [i for i,x in enumerate(self) if filtr(x)]
my_list = MyList([1,0,3,5,1])
my_list.indices(lambda x: x==1)
I elaborated a bit more on that topic here: http://tinyurl.com/jajrr87
'program story' 카테고리의 다른 글
'source'속성을 'org.eclipse.jst.jee.server : JSFTut'로 설정하면 일치하는 속성을 찾지 못했습니다. (0) | 2020.08.16 |
---|---|
emacs에서 활성 부 모드를 어떻게 나열합니까? (0) | 2020.08.15 |
파생 클래스 생성자에서 기본 클래스 멤버 변수를 어떻게 초기화 할 수 있습니까? (0) | 2020.08.15 |
Application.ThreadException과 AppDomain.CurrentDomain.UnhandledException의 차이점은 무엇입니까? (0) | 2020.08.15 |
Maven의 DistributionManagement 조직 전체를 지정하는 방법은 무엇입니까? (0) | 2020.08.15 |