By y2k


2009-11-11 00:30:54 8 Comments

Consider the following:

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

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

How do I get the number of elements in the list items?

7 comments

@Alec Alameddine 2019-05-25 03:09:52

In terms of how len() actually works, this is its C implementation:

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 is the maximum length that the object can have. PyObject_Size() is a function that returns the size of an object. If it cannot determine the size of an object, it returns -1. In that case, this code block will be executed:

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

And an exception is raised as a result. Otherwise, this code block will be executed:

return PyLong_FromSsize_t(res);

res which is a C integer, is converted into a python long and returned. All python integers are stored as longs since Python 3.

@Jonathan Komar 2017-12-06 18:14:14

And for completeness, it is possible without using the len() function (I would not condone this as a good option DO NOT PROGRAM LIKE THIS IN PYTHON):

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

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

(The colon in list[:] is implicit and is therefore also optional.)

The lesson here for new programmers is: You can’t get the number of items in a list without counting them at some point. Computationally, it is better to keep track of the number of items as you add them. See Naftuli Kay‘s answer.

@S. Salman 2018-03-23 17:32:19

Where did the OP say that he doesn't want to use the len() function?

@Jonathan Komar 2018-03-23 17:33:37

@GeorgeJ.Adams Where is your creative thinking cap? My answer answers the OP, albeit differently. We value a multiplicity of answers here at StackExchange, right?

@S. Salman 2018-03-23 17:37:40

Agreed. But the thing is in this case there is no reason to use your code v. the one liner. It it computationally faster? Is it easier to program this way? Multiple answers are welcome if they show a new dimension.

@Jonathan Komar 2018-04-05 15:49:30

@GeorgeJ.Adams I agree. But that is also not a reason to downvote this answer. I stand by my diversity argument.

@Brandon Ling 2018-05-25 18:35:50

@Jonathan Komar i disagree, if the OP was looking for creative non-efficient ways of doing it, he would have specified. Some questions can be answered 1 million different ways, but no one wants to read thru 1 million different answers

@Jonathan Komar 2018-05-25 20:01:48

@BrandonLing You’re entitled to that opinion. That is what the voting system is for. You made a bold statement however: “no one wants...” Maybe some people want multiple approaches to better understand the best solution.

@Brandon Ling 2018-05-26 14:55:40

@JonathanKomar Let me rephrase. People come to this question for the same objective of the OP. If people wanted creative ways for solving the issue, it would probably go under a different question or forum. Alternative solutions make sense when the best answer has some type of limitation. When will this answer ever make sense over the best answer? Why not just give an answer written in binary?

@TripleAntigen 2019-03-19 13:52:29

I am personally glad to find the example containing list[:], I found this answer while trying to find out why a code sample used the exact syntax with the colon. Thanks Jonathan NOTE: people end up at this page for all kinds of reasons, and not just for the answer the OP asked

@Granny Aching 2019-04-30 19:13:31

Why for item in list[:]:? Why not for item in list:? Also, I'd use += 1 to increment.

@Jonathan Komar 2019-05-02 06:29:06

@GrannyAching I explicitly mentioned the optional colon (range specifier). I left the range specifier in there for educational purposes-it is beneficial to know it is implied. A list type [] is inferred as well, as you suggest-equivalent to my code. The increment operator is also equivalent to adding 1 to an exisiting variable, yet shorter in all cases. So I‘d agree that it should be used if that is your reasoning. This code should not be put into production anywhere, anyway (except when learning programming).

@MSeifert 2017-04-07 19:03:33

Besides len you can also use operator.length_hint (requires Python 3.4+). For a normal list both are equivalent, but length_hint makes it possible to get the length of a list-iterator, which could be useful in certain circumstances:

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

But length_hint is by definition only a "hint", so most of the time len is better.

I've seen several answers suggesting accessing __len__. This is all right when dealing with built-in classes like list, but it could lead to problems with custom classes, because len (and length_hint) implement some safety checks. For example, both do not allow negative lengths or lengths that exceed a certain value (the sys.maxsize value). So it's always safer to use the len function instead of the __len__ method!

@gnud 2009-11-11 00:33:22

The len() function can be used with several different types in Python - both built-in types and library types. For example:

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

Official 2.x documentation is here: len()
Official 3.x documentation is here: len()

@Aaron Hall 2014-11-25 21:51:55

How to get the size of a list?

To find the size of a list, use the builtin function, len:

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

And now:

len(items)

returns 3.

Explanation

Everything in Python is an object, including lists. All objects have a header of some sort in the C implementation.

Lists and other similar builtin objects with a "size" in Python, in particular, have an attribute called ob_size, where the number of elements in the object is cached. So checking the number of objects in a list is very fast.

But if you're checking if list size is zero or not, don't use len - instead, put the list in a boolean context - it treated as False if empty, True otherwise.

From the docs

len(s)

Return the length (the number of items) of an object. The argument may be a sequence (such as a string, bytes, tuple, list, or range) or a collection (such as a dictionary, set, or frozen set).

len is implemented with __len__, from the data model docs:

object.__len__(self)

Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn’t define a __nonzero__() [in Python 2 or __bool__() in Python 3] method and whose __len__() method returns zero is considered to be false in a Boolean context.

And we can also see that __len__ is a method of lists:

items.__len__()

returns 3.

Builtin types you can get the len (length) of

And in fact we see we can get this information for all of the described types:

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

Do not use len to test for an empty or nonempty list

To test for a specific length, of course, simply test for equality:

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

But there's a special case for testing for a zero length list or the inverse. In that case, do not test for equality.

Also, do not do:

if len(items): 
    ...

Instead, simply do:

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

or

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

I explain why here but in short, if items or if not items is both more readable and more performant.

@Shai Alon 2015-07-14 08:36:42

Answering your question as the examples also given previously:

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

print items.__len__()

@Aaron Hall 2016-10-26 15:10:21

In Python, names that start with underscores are semantically non-public methods and should not be used by users.

@Shai Alon 2016-12-04 16:30:10

1. __foo__: this is just a convention, a way for the Python system to use names that won't conflict with user names. 2. _foo: this is just a convention, a way for the programmer to indicate that the variable is private (whatever that means in Python). 3. __foo: this has real meaning: the interpreter replaces this name with _classname__foo as a way to ensure that the name will not overlap with a similar name in another class. * No other form of underscores have meaning in the Python world. * There's no difference between class, variable, global, etc in these conventions.

@Aaron Hall 2016-12-04 18:42:49

This Q&A explains why you shouldn't use the special methods directly as a user: stackoverflow.com/q/40272161/541136

@Shai Alon 2017-02-28 11:39:07

@AaronHall but for len function it's almost the same. It might be faster for very large variables. However, I get your point and we should use len(obj) and not obj.__len__().

@Naftuli Kay 2013-04-19 21:51:10

While this may not be useful due to the fact that it'd make a lot more sense as being "out of the box" functionality, a fairly simple hack would be to build a class with a length property:

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

You can use it like so:

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

Essentially, it's exactly identical to a list object, with the added benefit of having an OOP-friendly length property.

As always, your mileage may vary.

@Tadhg McDonald-Jensen 2016-06-13 02:17:59

just so you know, you can just do length = property(len) and skip the one line wrapper function and keep the documentation / introspection of len with your property.

Related Questions

Sponsored Content

20 Answered Questions

39 Answered Questions

[SOLVED] How to make a flat list out of list of lists

19 Answered Questions

[SOLVED] How do I remove an element from a list by index in Python?

  • 2009-03-09 18:16:11
  • Joan Venge
  • 2193695 View
  • 1230 Score
  • 19 Answer
  • Tags:   python list

30 Answered Questions

[SOLVED] How do I check if a list is empty?

  • 2008-09-10 06:20:11
  • Ray Vega
  • 2218123 View
  • 3237 Score
  • 30 Answer
  • Tags:   python list

15 Answered Questions

[SOLVED] What are metaclasses in Python?

38 Answered Questions

[SOLVED] What does the "yield" keyword do?

28 Answered Questions

[SOLVED] Finding the index of an item given a list containing it in Python

  • 2008-10-07 01:39:38
  • Eugene M
  • 3244849 View
  • 2674 Score
  • 28 Answer
  • Tags:   python list indexing

39 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

17 Answered Questions

[SOLVED] How to make a chain of function decorators?

13 Answered Questions

[SOLVED] Getting the last element of a list in Python

  • 2009-05-30 19:28:53
  • Janusz
  • 1627408 View
  • 1691 Score
  • 13 Answer
  • Tags:   python list indexing

Sponsored Content