0

If we have a list s, is there any difference between calling list(s) versus s[:]? It seems to me like they both create new list objects with the exact elements of s.

4 Answers 4

4

In both cases, they should create a (shallow) copy of the list.

Note that there is one corner case (which is hardly worth mentioning) where it might be different...

list = tuple  # Don't ever do this!
list_copy = list(some_list)  # Oops, actually it's a tuple ...
actually_list_copy = some_list[:]

With that said, nobody in their right mind should ever shadow the builtin list like that.

My advice, use whichever you feel is easier to read and works nicely in the current context.

  • list(...) makes it explicit that the output is a list and will make a list out of any iterable.
  • something[:] is a common idiom for "give me a shallow copy of this sequence, I don't really care what kind of sequence it is ...", but it doesn't work on arbitrary iterables.
Sign up to request clarification or add additional context in comments.

2 Comments

Not that it is super important, but [:] generally outperforms list(). Running a simple timeit test with the list [1, 2, 3] yields 0.9552267117748205 for list() and 0.4996651809098642 for [:]. But like I said, this is somewhat nitpicking; the time difference is negligible in most cases.
@iCodez -- That's true, I've come across it before. The reasoning is that list(...) requires a global lookup which is somewhat expensive. And the global lookup is required because of the crazy case where a user shadows list. With slicing, the method lookup is done once (during bytecode generation) and is simply invoked on the object. There might be other reasons as well. . . the implementation could probably optimize list.__getitem__ as it can know the memory locations of the objects in the output easily, but list might resort to calling .next() a bunch of times...
1

list() is better - it's more readable. Other than that there is no difference.

Comments

1

The short answer is use list(). In google type python [:] then type python list.

If s is a list then there is no difference, but will s always be a list? Or could it be a sequence or a generator?

In [1]: nums = 1, 2, 3

In [2]: nums
Out[2]: (1, 2, 3)

In [3]: nums[:]
Out[3]: (1, 2, 3)

In [4]: list(nums)
Out[4]: [1, 2, 3]

In [7]: strings = (str(x) for x in nums)

In [8]: strings
Out[8]: <generator object <genexpr> at 0x7f77be460550>

In [9]: strings[:]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-358af12435ff> in <module>()
----> 1 strings[:]

TypeError: 'generator' object has no attribute '__getitem__'

In [10]: list(strings)
Out[10]: ['1', '2', '3']

Comments

0

I didn't realize, but as ventsyv mentioned, s[:] and list(s) both create a copy of s. Note you can check if an object is the same using is and id() can be used to get the object's memory address to actually see if they are the same or not.

>>> s = [1,2,3]
>>> listed_s = list(s)
>>> id(s)
44056328
>>> id(listed_s) # different
44101840
>>> listed_s is s
False
>>> bracket_s = s[:]
>>> bracket_s is s
False
>>> id(bracket_s)
44123760
>>> z = s # points to the same object in memory
>>> z is s
True
>>> id(z)
44056328
>>>

id(...) id(object) -> integer

Return the identity of an object.  This is guaranteed to be unique among
simultaneously existing objects.  (Hint: it's the object's memory address.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.