6

I have a function where I am returning two values. I would like to put the two values directly into two different arrays. I know how to return the output as two different values to be later added to the array, but I don't want to have the temporary place holders. An example is shown below.

def two_outputs():
    output_one = 5
    output_two = 6
    return output_one, output_two

one_array = []        # initialize array
two_array = []        # initialize array

a, b = two_outputs()  # get values

one_array.append(a)   # store first value in first array
two_array.append(b)   # store second value in first array

Ideally I would like to not use a and b and have to append at a later on in the code. I would like to append the output of the function directly to the two arrays. Is this even possible?

Thanks for any help. I hope I did this correctly as this is my first post. You guys have helped me quite a bit with programming issues already.

UPDATE: I guess based on the responses below that it is not possible to do this directly. Thanks for everyone's help in finding other ways to accomplish the goal.

2
  • 2
    why do you want to do this? what's wrong with temporary place holders? Commented Dec 13, 2011 at 19:31
  • 1
    I am doing a lot of work gathering information from a database, creating functions that return many values. I don't like the temporary place holders because it adds steps to the code, and I want the code smaller / shorter. Besides that, there is no technical reason. I am just curious if it is possible get the output of the function directly to two different arrays(or more). Based on the answers below, it looks like it is not possible. Commented Dec 13, 2011 at 19:45

5 Answers 5

5

How about using a helper function?

def zippend(lists, values):
  assert len(lists) == len(values)
  for l,v in zip(lists, values):
    l.append(v)

zippend((one_array, two_array), two_outputs())

The function zippend takes two parameters. The first is an iterable of Lists (what you are referring to as "arrays" are actually Lists in python). The second is an iterable of values to be appended to those lists.

It can take as many lists and values as you want, as long as the number of lists matches the number of values (one value per list).

EDIT: If two_outputs() were to return a tuple of Lists to be concatenated onto one_array and two_array, then you could change the function to use extend instead of append:

def zextend(lists, values):
  assert len(lists) == len(values)
  for l,v in zip(lists, values):
    l.extend(v)

Or, if you really wanted to, you could use a single function that had an if-statement that checked what kind of values it was getting and appended or extended as appropriate.

Sign up to request clarification or add additional context in comments.

6 Comments

I suggest the name "zippend".
@Laurence I like it! Edited!
That looks pretty interesting. Can you explain the bounds of it a little more? I assume you could uses as many arrays and outputs as you wanted?
I am curious how this method would work if the function returned an array, instead of a single value.
@ruffryder Edited to address your first comment.
|
1

Assuming I understand you correctly, you would need to define your arrays prior to the declaration of the function.

one_array, two_array = [], []

def two_outputs():
    one_array.append(5)
    two_array.append(6)

#call function
two_outputs()

print one_array, two_array
#[5] [6]

Comments

1

You could always alter your function to return a tuple of lists:

def test():
   # some code
   return [a], [b]

a, b = test()

that will make both a and b lists when they're returned

Comments

0

Can be done in one line with the following generator. The call to "any" is just so that the generator is consumed, and therefore the expressions in it get executed.

any(lst.append(item) for lst,item in zip((one_array, two_array), two_outputs()))

NB. I do not recomend this programing style - it gets harder to read. Probably, if it where too frequent an idiom, I'd write a short helper function for the assignment like:

def multi_append(lists, multi_function, *args, **kw):
    for lst, result in zip(lists, multi_function(*args, **kw)):
         lst.append(result)

And on the "body" of the code, just write:

multi_append((array_one, array_two), two_outputs)

For the sake of completeness, I am adding a suggestion that would allow you to use the assignment operator.

What is needed in this case, is a custom List object that has a property wich performs the appending. Creating such a class is a 2 liner, but then, he lists in your code would have to be from this class:

class MList(list):
    last = property(lambda s:s[-1], list.append)

array_one, array_two = MList(), MList()

array_one.last, array_two.last = two_outputs()

Comments

0

A simple solution uses a smart combination of the list constructor with the map and the zip functions:

def two_outputs(x):
    return (x**2, x**3)
one_array, two_array = map(list, zip(*[two_outputs(x) for x in range(1, 5)]))
print(one_array, two_array)

Output:

[1, 4, 9, 16] [1, 8, 27, 64]

The zip function, first, returns all first elements of all tuples. These get maped on the list constructor that returns one_array. Next, zip returns all second elements, which again get mapped on list resulting in two_array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.