source

목록 또는 태플에서 항목을 명시적으로 선택

manycodes 2023. 4. 16. 15:22
반응형

목록 또는 태플에서 항목을 명시적으로 선택

다음과 같은 Python 목록이 있습니다(태플일 수도 있습니다).

myList = ['foo', 'bar', 'baz', 'quux']

말할 수 있다

>>> myList[0:3]
['foo', 'bar', 'baz']
>>> myList[::2]
['foo', 'baz']
>>> myList[1::2]
['bar', 'quux']

인덱스에 특정 패턴이 없는 항목을 명시적으로 선택하려면 어떻게 해야 합니까?예를 들어, 나는 선택하기를 원한다.[0,2,3]또는 1000개의 매우 큰 리스트 중에서 선택하고 싶다.[87, 342, 217, 998, 500]그런 Python 구문이 있나요?다음과 같은 모습:

>>> myBigList[87, 342, 217, 998, 500]
list( myBigList[i] for i in [87, 342, 217, 998, 500] )

python 2.5.2와 답변을 비교했습니다.

  • 19.7 용도:[ myBigList[i] for i in [87, 342, 217, 998, 500] ]

  • 20.6 용도:map(myBigList.__getitem__, (87, 342, 217, 998, 500))

  • 22.7 usec:itemgetter(87, 342, 217, 998, 500)(myBigList)

  • 24.6 용도:list( myBigList[i] for i in [87, 342, 217, 998, 500] )

Python 3에서는 첫 번째가 네 번째와 동일하게 변경되었음을 유의하십시오.


또 다른 옵션은 첫 번째로numpy.array목록 또는 목록을 통해 인덱싱할 수 있습니다.numpy.array:

>>> import numpy
>>> myBigList = numpy.array(range(1000))
>>> myBigList[(87, 342, 217, 998, 500)]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: invalid index
>>> myBigList[[87, 342, 217, 998, 500]]
array([ 87, 342, 217, 998, 500])
>>> myBigList[numpy.array([87, 342, 217, 998, 500])]
array([ 87, 342, 217, 998, 500])

tuple슬라이스와 같은 방식으로 동작하지 않습니다.

이건 어때?

from operator import itemgetter
itemgetter(0,2,3)(myList)
('foo', 'baz', 'quux')

목록 이해는 다음과 같습니다.

L = ['a', 'b', 'c', 'd', 'e', 'f']
print [ L[index] for index in [1,3,5] ]

작성:

['b', 'd', 'f']

그게 당신이 찾고 있는 건가요?

기본 제공은 아니지만 다음과 같은 경우 "인덱스"로 사용되는 목록의 하위 클래스를 만들 수 있습니다.

class MyList(list):

    def __getitem__(self, index):
        if isinstance(index, tuple):
            return [self[i] for i in index]
        return super(MyList, self).__getitem__(index)


seq = MyList("foo bar baaz quux mumble".split())
print seq[0]
print seq[2,4]
print seq[1::2]

인쇄

foo
['baaz', 'mumble']
['bar', 'quux']
>>> map(myList.__getitem__, (2,2,1,3))
('baz', 'baz', 'bar', 'quux')

직접 만들 수도 있습니다.List인수로서 튜플을 지원하는 클래스__getitem__할 수 있다면myList[(2,2,1,3)].

지적하고 싶은 것은 아이템게터의 구문도 매우 깔끔해 보이지만, 큰 리스트에서는 동작이 느립니다.

import timeit
from operator import itemgetter
start=timeit.default_timer()
for i in range(1000000):
    itemgetter(0,2,3)(myList)
print ("Itemgetter took ", (timeit.default_timer()-start))

Itemgetter는 1.065209062149279를 가져갔다.

start=timeit.default_timer()
for i in range(1000000):
    myList[0],myList[2],myList[3]
print ("Multiple slice took ", (timeit.default_timer()-start))

여러 슬라이스가 0.6225321444745759를 차지했다.

또 다른 가능한 해결책:

sek=[]
L=[1,2,3,4,5,6,7,8,9,0]
for i in [2, 4, 7, 0, 3]:
   a=[L[i]]
   sek=sek+a
print (sek)

예를 들어 다음과 같은 부울 numpy 배열이 있는 경우mask

[mylist[i] for i in np.arange(len(mask), dtype=int)[mask]]

모든 시퀀스 또는 np.array에 대해 작동하는 람다:

subseq = lambda myseq, mask : [myseq[i] for i in np.arange(len(mask), dtype=int)[mask]]

newseq = subseq(myseq, mask)

다음은 한 줄의 람다입니다.

list(map(lambda x: mylist[x],indices))

여기서:

mylist=['a','b','c','d','e','f','g','h','i','j']
indices = [3, 5, 0, 2, 6]

출력:

['d', 'f', 'a', 'c', 'g']

언급URL : https://stackoverflow.com/questions/6632188/explicitly-select-items-from-a-list-or-tuple

반응형