0

Given following lists:

arr = [1, 5, 2, 6, 3, 7, 4]
cmds = [[1, 3, 2], [3, 5, 1], [2, 7, 4]]

For each command in cmds, I want to obtain

[arr[1:3][2], arr[3:5][1], arr[2:7][4]]

I tried:

list(map(lambda x: arr[x[0]:x[1]][x[2]], cmds))

But could I possibly write a cleaner code than the above? I want to use 3 positional arguments i, j, k instead of x alone:

list(map(lambda i, j, k: arr[i:j][k], cmds)) # This gives TypeError
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
cryptnomy
  • 13
  • 2

1 Answers1

1

Argument unpacking in function signatures has been removed in Python 3 (See this answer).

Here are some alternatives:

Solution 1:

If you want to get the same effect with clean code, @bereal's answer is a good choice:

[arr[i:j][k] for i, j, k in cmds]

This is a for loop / list comprehension, so unpacking is allowed.

Solution 2:

If you insist on using map, you can do so with nested lambdas:

list(map(lambda cmd: (lambda i,j,k: arr[i:j][k])(*cmd), cmds))

In the outer lambda, cmd is assigned an element in cmds, which corresponds to a list of length 3. The return value of this outer lambda is an IIFE that defines an inner lambda taking 3 arguments, which we pass in by unpacking the cmd argument from the outer lambda.

Solution 3:

This one's by @KellyBundy:

list(map(lambda i,j,k: arr[i:j][k], *zip(*cmds)))

In this case, this is equivalent to

arr = [1, 5, 2, 6, 3, 7, 4]
cmds = [[1, 3, 1], [3, 5, 1], [2, 7, 4]]

c1 = (1, 3, 2)
c2 = (3, 5, 7)
c3 = (1, 1, 4)
list(map(lambda i,j,k: arr[i:j][k], c1, c2, c3))
Fractalism
  • 1,231
  • 3
  • 12
  • 1
    if you write `arr[i:j][k:k+1]` then it will get an empty list when the index is out of range instead of an exception, when there is a correct index then it will be a one element list instead. – Gábor Fekete Jan 24 '23 at 09:10
  • 1
    You have a point, but it adds extra complexity to the code since each resulting element will need to be fetched with an additional if-else or for loop. Whether that should be implemented depends on OP's use case and whether the `cmds` variable can be trusted to provide valid information. – Fractalism Jan 24 '23 at 09:20