[python] 목록의 요소 수를 어떻게 얻습니까?

다음을 고려하세요:

items = []
items.append("apple")
items.append("orange")
items.append("banana")

# FAKE METHOD:
items.amount()  # Should return 3

목록에서 요소의 수를 어떻게 얻 items습니까?



답변

len()함수는 파이썬에서 내장 타입과 라이브러리 타입의 여러 다른 타입과 함께 사용될 수 있습니다. 예를 들면 다음과 같습니다.

>>> len([1,2,3])
3

공식 2.x 설명서는 여기 :
공식 3.x 설명서는 여기 :len()
len()


답변

목록의 크기를 얻는 방법?

리스트의 크기를 찾으려면 내장 함수를 사용하십시오 len.

items = []
items.append("apple")
items.append("orange")
items.append("banana")

그리고 지금:

len(items)

3을 반환합니다.

설명

파이썬의 모든 것은리스트를 포함한 객체입니다. 모든 객체는 C 구현에서 일종의 헤더를 가지고 있습니다.

파이썬에서 “크기”를 가진 목록 및 기타 유사한 내장 객체는 특히 ob_size객체의 요소 수가 캐시되는 이라는 속성을 갖습니다 . 따라서 목록의 객체 수를 확인하는 것이 매우 빠릅니다.

그러나 목록 크기가 0인지 여부를 확인하는 경우 사용하지 마십시오. len대신 목록을 부울 컨텍스트에 넣습니다 . 비어 있으면 False로 처리하고 그렇지 않으면 True로 처리합니다 .

로부터 문서

len(s)

객체의 길이 (항목 수)를 반환합니다. 인수는 시퀀스 (예 : 문자열, 바이트, 튜플, 목록 또는 범위) 또는 컬렉션 (예 : 사전, 세트 또는 고정 세트) 일 수 있습니다.

len__len__데이터 모델 문서 에서 로 구현됩니다 .

object.__len__(self)

내장 함수를 구현하기 위해 호출됩니다 len(). 객체의 길이, 정수> = 0을 반환해야합니다. 또한 __nonzero__()[Python 2 또는 __bool__()Python 3] 메서드를 정의하지 않고 __len__()0을 반환 하는 메서드는 부울 컨텍스트에서 false로 간주됩니다.

그리고 우리 __len__는 이것이리스트의 방법 이라는 것을 알 수 있습니다 :

items.__len__()

3을 반환합니다.

내장 유형은 len(길이)를 얻을 수 있습니다

실제로 우리는 설명 된 모든 유형에 대해이 정보를 얻을 수 있습니다.

>>> all(hasattr(cls, '__len__') for cls in (str, bytes, tuple, list,
                                            xrange, dict, set, frozenset))
True

len비어 있거나 비어 있지 않은 목록을 테스트 하는 데 사용하지 마십시오

물론 특정 길이를 테스트하려면 동등성을 테스트하십시오.

if len(items) == required_length:
    ...

그러나 길이가 0 인리스트 나 반대를 테스트하는 특별한 경우가 있습니다. 이 경우 평등을 테스트하지 마십시오.

또한하지 마십시오 :

if len(items):
    ...

대신 간단하게 수행하십시오.

if items:     # Then we have some items, not empty!
    ...

또는

if not items: # Then we have an empty list!
    ...

나는 왜 여기에 설명 하지만, 짧은에, if items또는 if not items둘 다 더 읽기 더 성능이 좋은 것입니다.


답변

이 기능은 “즉시 사용 가능한”기능으로 훨씬 더 의미가 있기 때문에 유용하지 않을 수 있지만 상당히 간단한 해킹은 length속성 을 사용하여 클래스를 작성하는 것입니다 .

class slist(list):
    @property
    def length(self):
        return len(self)

다음과 같이 사용할 수 있습니다.

>>> l = slist(range(10))
>>> l.length
10
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

본질적으로 목록 객체와 정확히 동일하며 OOP 친화적 인 length속성 을 갖는 이점이 있습니다.

항상 그렇듯이 마일리지는 다를 수 있습니다.


답변

게다가 len당신도 사용할 수 있습니다 operator.length_hint(Python 3.4+ 필요). 정상적인 경우 list둘 다 동일하지만 length_hint특정 상황에서 유용 할 수있는 목록 반복자의 길이를 얻을 수 있습니다.

>>> from operator import length_hint
>>> l = ["apple", "orange", "banana"]
>>> len(l)
3
>>> length_hint(l)
3

>>> list_iterator = iter(l)
>>> len(list_iterator)
TypeError: object of type 'list_iterator' has no len()
>>> length_hint(list_iterator)
3

그러나 length_hint정의상 “힌트”일 뿐이므로 대부분의 시간 len이 더 좋습니다.

에 액세스 할 것을 제안하는 몇 가지 답변을 보았습니다 __len__. 클래스처럼 내장을 다룰 때 모든 권리 list,하지만 때문에 사용자 정의 클래스에 문제가 발생할 수있다 len(그리고 length_hint일부 안전 점검)를 구현합니다. 예를 들어, 둘 다 음수 길이 또는 특정 값 ( sys.maxsize값) 을 초과하는 길이를 허용하지 않습니다 . 따라서 메소드 len대신 함수 를 사용하는 것이 항상 더 안전합니다 __len__!


답변

이전에 제공된 예제로 질문에 답하십시오.

items = []
items.append("apple")
items.append("orange")
items.append("banana")

print items.__len__()


답변

그리고 완전성을 위해 (주로 교육적) len()기능 을 사용하지 않고도 가능 합니다. 나는 이것을 좋은 옵션으로 용납하지 않을 것이다. 이것은 PYTHON 에서 이것을 좋아하지 않는다 . 그러나 그것은 알고리즘 학습을위한 목적을 제공한다.

def count(list):
    item_count = 0
    for item in list[:]:
        item_count += 1
    return item_count

count([1,2,3,4,5])

콜론 list[:]은 암시 적이므로 선택 사항입니다.

새로운 프로그래머를위한 교훈은 다음과 같습니다. 어떤 시점에서 계산하지 않으면 목록의 항목 수를 얻을 수 없습니다. 문제는 다음과 같습니다. 언제 그들을 계산하기에 좋은시기입니까? 예를 들어, 소켓에 대한 연결 시스템 호출 (C로 작성)과 같은 고성능 코드 connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);는 요소의 길이를 계산하지 않습니다 (호출 코드에 대한 책임 부여). 길이를 먼저 계산하는 단계를 저장하기 위해 주소의 길이가 전달됩니다. 또 다른 옵션 : 계산 상, 전달하는 객체 내에 항목을 추가 할 때 항목 수를 추적하는 것이 좋습니다. 이것이 메모리에서 더 많은 공간을 차지한다고 생각하십시오. Naftuli Kay의 답변을 참조하십시오 .

메모리에서 더 많은 공간을 차지하면서 성능을 향상시키기 위해 길이를 추적하는 예. 길이가 추적되기 때문에 len () 함수를 사용하지 마십시오.

class MyList(object):
    def __init__(self):
        self._data = []
        self.length = 0 # length tracker that takes up memory but makes length op O(1) time


        # the implicit iterator in a list class
    def __iter__(self):
        for elem in self._data:
            yield elem

    def add(self, elem):
        self._data.append(elem)
        self.length += 1

    def remove(self, elem):
        self._data.remove(elem)
        self.length -= 1

mylist = MyList()
mylist.add(1)
mylist.add(2)
mylist.add(3)
print(mylist.length) # 3
mylist.remove(3)
print(mylist.length) # 2


답변

len()실제로 어떻게 작동 하는지에 관해서 는 이것이 C 구현입니다 .

static PyObject *
builtin_len(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/
{
    Py_ssize_t res;

    res = PyObject_Size(obj);
    if (res < 0) {
        assert(PyErr_Occurred());
        return NULL;
    }
    return PyLong_FromSsize_t(res);
}

Py_ssize_t객체가 가질 수있는 최대 길이입니다. PyObject_Size()객체의 크기를 반환하는 함수입니다. 객체의 크기를 결정할 수 없으면 -1을 반환합니다. 이 경우이 코드 블록이 실행됩니다.

if (res < 0) {
        assert(PyErr_Occurred());
        return NULL;
    }

결과적으로 예외가 발생합니다. 그렇지 않으면이 코드 블록이 실행됩니다.

return PyLong_FromSsize_t(res);

resC정수, 파이썬로 변환 long하고 돌아왔다. 모든 파이썬 정수는 longs파이썬 3부터 저장됩니다 .