It is an example of slice notation, and what it does depends on the type of population. If population is a list, this line will create a shallow copy of the list. For an object of type tuple or a str, it will do nothing (the line will do the same without [:]), and for a (say) NumPy array, it will create a new view to the same data.
python - What does [:] mean? - Stack Overflow
python - What's the difference between [] and {} vs list() and dict()? - Stack Overflow
How "list" is implemented in Python?
Python list
Videos
It is an example of slice notation, and what it does depends on the type of population. If population is a list, this line will create a shallow copy of the list. For an object of type tuple or a str, it will do nothing (the line will do the same without [:]), and for a (say) NumPy array, it will create a new view to the same data.
It might also help to know that a list slice in general makes a copy of part of the list. E.g. population[2:4] will return a list containing population[2] and population[3] (slicing is right-exclusive). Leaving away the left and right index, as in population[:] they default to 0 and length(population) respectively, thereby selecting the entire list. Hence this is a common idiom to make a copy of a list.
In terms of speed, it's no competition for empty lists/dicts:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
and for non-empty:
>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267
Also, using the bracket notation lets you use list and dictionary comprehensions, which may be reason enough.
In my opinion [] and {} are the most pythonic and readable ways to create empty lists/dicts.
Be wary of set()'s though, for example:
this_set = {5}
some_other_set = {}
Can be confusing. The first creates a set with one element, the second creates an empty dict and not a set.
Lately finding myself looking around in builtins.py file trying to learn/understand how the language works. Today I was reading about lists and how they work and etc. And as usually I end up in a class list in builtins.py file. I am now surprised that all the functions of list class is empty. For example, method append has 'pass' in it. And that is it.
Here is a code:
class list(object):
"""
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list.
The argument must be an iterable if specified.
"""
def append(self, *args, **kwargs): # real signature unknown
""" Append object to the end of the list. """
pass
def clear(self, *args, **kwargs): # real signature unknown
""" Remove all items from list. """
pass
def copy(self, *args, **kwargs): # real signature unknown
""" Return a shallow copy of the list. """
passI wonder how this works? Why all methods are empty?
Can someone give me a break down on python lists I'm not understanding
It's essentially a combination of tuple/list unpacking and *args iterable unpacking. Each iterable is getting unpacked on each iteration of the for loop.
First let's look at a simple tuple/list unpacking:
>>> x, y = (1, 2)
>>> x
1
>>> y
2
# And now in the context of a loop:
>>> for x, y in [(1, 2), (3, 4)]:
>>> print(f'x={x}, y={y}')
"x=1, y=2"
"x=3, y=4"
Now consider the following (and imagine the same concept within the loop as shown above):
>>> x, y = (1, 2, 3)
ValueError: too many values to unpack (expected 2)
>>> x, *y = 1, 2, 3
>>> x
1
>>> y
[2, 3]
Note how * allows y to consume all remaining arguments.
This is similar to how you would use * in a function - it allows an unspecified number of arguments and it consumes them all.
You can see more examples of (*args) usage here.
>>> def foo(x, *args):
>>> print(x)
>>> print(args)
>>>foo(1, 2, 3, 4)
1
[2, 3, 4]
As for practical examples, here is a quick one:
>>> names = ("Jack", "Johnson", "Senior")
>>> fist_name, *surnames = names
>>> print(surnames)
["Johnson", "Senior"]
Basically * indicates n number of countless elements.
Example :
x=1,2,4,6,9,8
print(type(x))
print(x)
Output:
<class 'tuple'>
(1, 2, 4, 6, 9, 8)
y,*x=1,2,4,6,9,8
print(type(x))
print(x)
Output:
<class 'list'>
[2, 4, 6, 9, 8]