3

I don't know whether it is anyway possible in Python and that is the reason why I ask it here.

I have a Python function that returns a tuple:

def my_func(i):
    return i * 2, 'a' * i

This is just a dumb function that given a number k, it returns k * 2 as is and another string is the letter 'a' concatenated k times.

I want now to form two lists, calling the function with i = 0...9, I want to create one list with all the first values and another one with the rest of them.

What I do with my current knowledge is:

Option 1: Run the same list comprehension two times, that is not very efficient:

first_vals = [my_func(i)[0] for i in range(10)]
second_vals = [my_func(i)[1] for i in range(10)]

Option 2: Avoiding list comprehensions:

first_vals = []
second_vals = []
for i in range(10):
    f, s = my_func(i)
    first_vals.append(f)
    second_vals.append(s)

Option 3: Use list comprehension to get a list of tuples and then two other list comprehension to copy the values. It is better than Option 1, as here my_func() is only called once for each i:

ret = [my_func(i) for i in range(10)]
first_vals = [r[0] for r in ret]
second_vals = [r[1] for r in ret]

Is it possible to somehow use the list comprehension feature in order to return two lists in one command and one iteration, assigning each returned parameter into a different list?

AgvaniaRekuva
  • 565
  • 1
  • 5
  • 12
  • a inverse zip function? : `lst1, lst2 = zip(*zipped_list)` - from the dupe answer https://stackoverflow.com/a/13635074/7505395 – Patrick Artner Jan 13 '18 at 15:29
  • 9
    Possible duplicate of [What is the inverse function of zip in python?](https://stackoverflow.com/questions/13635032/what-is-the-inverse-function-of-zip-in-python) - wich is marked ad dupe for [/transpose-unzip-function-inverse-of-zip](https://stackoverflow.com/questions/19339/transpose-unzip-function-inverse-of-zip) . SO-**Search** for the win ... – Patrick Artner Jan 13 '18 at 15:29
  • 1
    @PatrickArtner what you suggest is a post that helps those who already know what `zip()` is, and look for something very specific. You had known the answer and thus found a post that answers it as well, but I did not find a post with a similar *question* – AgvaniaRekuva Jan 13 '18 at 15:51
  • Thank you anyway for the answer in the comments, it is very useful – AgvaniaRekuva Jan 13 '18 at 15:52

1 Answers1

7

Option 4: Use the inverse of zip:

first_vals, second_vals = zip(*[my_func(i) for i in range(10)])

As Mark Dickinson pointed out in the comment this will lead to tuples for first_vals and second_vals. If you need them to be of type list you can, for example, apply a map:

first_vals, second_vals = map(list, zip(*[my_func(i) for i in range(10)]))
NKahle
  • 142
  • 6
  • 2
    @PatrickArtner 1. You did not define `zipped_list`. 2. If your comment was supposed to be an answer, you should have posted it as one. – NKahle Jan 13 '18 at 15:37
  • 1
    Note that this makes `first_vals` and `second_vals` into `tuple`s rather than `list`s, which may or may not be good enough for the OP. – Mark Dickinson Jan 13 '18 at 15:37
  • 1
    That's great, thank you!! – AgvaniaRekuva Jan 13 '18 at 15:38
  • @AgvaniaRekuva you are welcome! consider accepting it as the correct answer, if it was helpful. – NKahle Jan 13 '18 at 15:39
  • @MarkDickinson you are right, I'll add your comment as clarification to the answer, if I may. – NKahle Jan 13 '18 at 15:40
  • 1
    @PatrickArtner so you thought the question should not be answered, that's why you answered it with a comment? I do not understand that reasoning. – NKahle Jan 13 '18 at 15:41
  • @PatrickArtner I have gone through the intros and everything, but I'm fairly new to SO. It was my understanding that comments should not answer questions, but maybe I'm wrong about that. Was not my intention to step on you toes or anything! – NKahle Jan 13 '18 at 15:43