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


1937

다음을 고려하세요:

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

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

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


23
분명히 목록의 요소 수를 요구하고 있습니다. 검색자가 메모리에있는 객체의 크기를 찾는다면 여기에 실제 질문과 답변이 있습니다 : 파이썬에서 객체의 크기를 어떻게 결정합니까?
Aaron Hall

답변:


2640

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

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

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


239

목록의 크기를 얻는 방법?

리스트의 크기를 찾으려면 내장 함수를 사용하십시오 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둘 다 더 읽기 더 성능이 좋은 것입니다.


75

이 기능은 "즉시 사용 가능한"기능으로 훨씬 더 의미가 있기 때문에 유용하지 않을 수 있지만 상당히 간단한 해킹은 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속성 을 갖는 이점이 있습니다.

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


19
단지 length = property(len)한 줄짜리 래퍼 기능을 건너 뛰고 len속성에 대한 문서 / 검사를 유지할 수 있습니다.
Tadhg McDonald-Jensen 2016

17

게다가 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__!


8

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

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

print items.__len__()

15
파이썬에서 밑줄로 시작하는 이름은 의미 상 비 공용적인 방법이므로 사용자가 사용해서는 안됩니다.
Aaron Hall

2
1. __foo__: 이것은 단지 규칙이며, 파이썬 시스템이 사용자 이름과 충돌하지 않는 이름을 사용하는 방법입니다. 2. _foo: 이것은 단지 관습에 불과합니다. 프로그래머가 변수가 private이라는 것을 나타내는 방법입니다 (Python에서 의미하는 것). 3. __foo: 이것은 실제 의미를 갖습니다. 인터프리터는이 이름을 _classname__foo다른 클래스의 유사한 이름과 겹치지 않도록하기 위해이 이름을 바꿉니다 . * 파이썬 세계에서 다른 형태의 밑줄은 의미가 없습니다. *이 규칙에서 클래스, 변수, 전역 등의 차이는 없습니다.
Shai Alon

4
이 Q & A에서는 특수 방법을 사용자로서 직접 사용해서는 안되는 이유를 설명합니다. stackoverflow.com/q/40272161/541136
Aaron Hall

@AaronHall 그러나 len 기능의 경우 거의 동일합니다. 매우 큰 변수의 경우 더 빠를 수 있습니다. 그러나 나는 당신의 요점을 얻었으며 obj .__ len __ ()이 아닌 len (obj)을 사용해야합니다.
Shai Alon

7

그리고 완전성을 위해 (주로 교육적) 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

for item in list[:]:? 왜 안돼 for item in list:? 또한 += 1증가시키는 데 사용 합니다.
Granny Aching

@GrannyAching 필자는 선택적 콜론 (범위 지정자)을 명시 적으로 언급했습니다. 교육 목적으로 범위 지정자를 그대로 두었습니다. 암시 적으로 알면 도움이됩니다. 내 코드와 동일하게 제안하는 것처럼 목록 유형 []도 유추됩니다. 증가 연산자는 기존 변수에 1을 더하는 것과 동일하지만 모든 경우에 더 짧습니다. 그래서 그것이 당신의 추론이라면 그것이 사용되어야한다는 것에 동의합니다. 이 코드는 어쨌든 (프로그래밍을 배우는 경우를 제외하고) 프로덕션 환경에 배치해서는 안됩니다.
Jonathan Komar

0

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부터 저장됩니다 .


3
C 구현에 대해 아는 것이 중요한 이유는 무엇입니까?
cs95

이 질문은 CPython에만 국한된 것이 아니기 때문에이 답변은 잘못된 결과 일 수 있습니다. PyPy, IronPython, ... 다르게 구현할 수 있습니다.
MSeifert
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.