1

I would like to build a function that gives me two lists as an output:

def times_10(i):
    out = i * 10
    return out, i
​
outpt,inpt = [times_10(i) for i in range(1,8)] #doesn't work

I have one way of doing it, but I have a feeling there must be something simpler:

a = [times_10(i) for i in range(1,8)]
outpt,inpt = list(map(list, zip(*a))) # this works

Expected output:

>>> outpt
[10, 20, 30, 40, 50, 60, 70]
>>> inpt
[1, 2, 3, 4, 5, 6, 7]
Shinobi_Atobe
  • 1,793
  • 1
  • 18
  • 35
  • You can skip the last call to `list`: `outpt,inpt = map(list, zip(*a))`. Other than that I do not see a more compact way. – norok2 Dec 20 '19 at 10:40
  • wasn't list comprehension meant to replace`map`? – Shinobi_Atobe Dec 20 '19 at 10:40
  • you could use a generator `outpt,inpt = (list(x) for x in zip(*a))`, but why? `map()` is shorter, should be faster here and arguably simpler to read (for once). – norok2 Dec 20 '19 at 10:43
  • Thanks, just learning the language and want to pick up all good habbits along the way! – Shinobi_Atobe Dec 20 '19 at 10:48
  • `map()` was never deprecated but for less simple constructs the comprehensions are deemed to be easier to read and write. Also, I am not sure why this was closed, the `zip(*items)` construct is already there in your question. Not sure how this is a duplicate of that... – norok2 Dec 20 '19 at 10:51

1 Answers1

2

You can unzip the comprehension:

out, in = zip(*[(i*10, i) for i in range(10)])

Example:

>>> out, inp = zip(*[(i*10, i) for i in range(10)])
>>> out
(0, 10, 20, 30, 40, 50, 60, 70, 80, 90)
>>> inp
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Netwave
  • 40,134
  • 6
  • 50
  • 93
  • but they are no longer `list`s – norok2 Dec 20 '19 at 10:35
  • 1
    Yes, this looks like the sought answer. However, it is worth mentioning that performing two separate list comprehensions is probably faster (and simpler) – Tony.H Dec 20 '19 at 10:36