This has not much to do with dynamic programming itself.
n, S = map[int, input[].split[]]
will query the user for input, and then split it into words, convert these words in integers, and unpack it into two variables n
and S
. This thus will succeed when the user enters two numbers [not more, not less].
It works as follows:
input[]
will query the user for input, and read one line of user input;.split[]
will split that input into a list of "words";map[int, ...]
will callint
on each word, it will to that lazily [although that is not important here]; andn, S = ...
will unpack the expression into two elements, and assign the first one ton
and the second one toS
.
For example:
>>> n, S = map[int, input[].split[]]
14 25
>>> n
14
>>> S
25
But it will error if you pass only one number, three numbers, etc. like:
>>> n, S = map[int, input[].split[]]
14
Traceback [most recent call last]:
File "", line 1, in
ValueError: not enough values to unpack [expected 2, got 1]
>>> n, S = map[int, input[].split[]]
14 25 37
Traceback [most recent call last]:
File "", line 1, in
ValueError: too many values to unpack [expected 2]
>>> n, S = map[int, input[].split[]]
foo bar
Traceback [most recent call last]:
File "", line 1, in
ValueError: invalid literal for int[] with base 10: 'foo'
The line:
w = list[map[int, input[].split[]]]
does more or less the same thing, but instead takes as input from the user a sequence of numbers. There can
be zero, one or more numbers. w
will store a list of numbers. The list[..]
part forces Python to evaluate the map[..]
eagerly.
dp = [0] * [S + 1]
Here we will construct a list with S + 1
zeros. In Python, you can multiply a list [and tuple] with an integer n. The result is a list [or tuple] that is n times as large as the original list, and it repeats the elements. For example:
>>> [1,4,2,5] * 3
[1, 4, 2, 5, 1, 4, 2, 5, 1, 4, 2, 5]
Since here the given list contains one zero, it will thus produce a list
that contains S+1
zeros.
Finally
dp[0] = 0
will set the first element to zero. But since that was already the case, this line is not very useful.
Let's break it down:
input[]
gets user input and returns a string, e.g."1 2 3 4 5"
input[].split[]
splits that input on whitespaces, e.g.["1", "2", "3", ...]
int[]
converts a string to a integer, e.g."1" -> 1
map[fn, sequence]
applies the functionfn
to each element in thesequence
, e.g.fn[sequence[0]], fn[sequence[1]], ...
map[int, input[].split[]]
appliesint
to each string element in the input, e.g.["1", "2", "3", ...] -> int["1"], int["2"], ...
list[]
turns any iterator/generator to a list, e.g.int["1"], int["2"], ... => [1, 2, 3, ...]
Example:
In []:
list[map[int, input[].split[]]]
Input:
1 2 3 4 5
Out[]:
[1, 2, 3, 4, 5]
Note: this is the same as, which may be easier to read:
In []:
[int[n] for n in input[].split[]]
Input:
1 2 3 4 5
Out[]:
[1, 2, 3, 4, 5]
You don't create an array this way, you create an object that will provide you the objects once you iterate over them. Meaning as in a for
loop
for v in arr:
do something with v
or when you would create another sequence from it, like with list[]
my_list = list[arr]
the point is that with a list you create a structure in RAM that will hold all the items upfront, which is often not what you actually need per se, so map
allows you to simply define what you want [that takes no
CPU or extra storage space] and only performs the actions when needed. If you do you need this as a list then a comprehension is preferable over map
:
mylist = [int[n] for n in input.split[]]
Sidenote: Python doesn't have a regular 'array', it has lists for ordered sequences that can be indexed. It does have specialized array for numerical values of a specific type but that's more oriented for low-level applications or for interfacing to other systems that need those kind of statically typed arrays.