Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a tuple out of a generator? Best Practice

I'm a neophyte programmer and I wanted to create a generator that would return me two values that I would use in another function as a tuple.

I don't understand why tuple(function_1(a,b)) returns ((1, 2),) while tuple(function_2(a,b)) will return a correct tuple.

I wonder what is going on here and what is the best syntax and eventually know if it is possible to retrieve a tuple from function_1.

Thanks in advance for any explanations!

>>> def function_1(a,b):
...     yield a,b
...
>>> def function_2(a,b):
...     yield a
...     yield b
...
>>> a = 1
>>> b = 2
>>>
>>> function_1(a,b)
<generator object function_1 at 0x1007931b0>
>>> function_2(a,b)
<generator object function_2 at 0x1007931f8>
>>> tuple(function_1(a,b))
((1, 2),)
>>> tuple(function_2(a,b))
(1, 2)
>>> for item in function_1(a,b):
...    print(item)
...
(1, 2)
>>> for item in function_2(a,b):
...    print(item)
...
1
2
like image 276
Etienne P. Avatar asked Aug 25 '15 10:08

Etienne P.


People also ask

How do you get an element out of a tuple?

To remove an element from a tuple: Convert the tuple to a list (lists are mutable). Use the list. remove() method to remove the item from the list. Convert the list back to a tuple.

Can you unpack a generator Python?

You can carry out the unpacking procedure for all kinds of iterables like lists, tuples, strings, iterators and generators.

How do you access a tuple inside a list?

Use a list comprehension to access tuples in a list. Use the list comprehension syntax [tuple[index] for tuple in list] to return a list of the items in index of each tuple in list .

How do you get a list value's tuple form?

Just like list data structure, a tuple is homogenous. Therefore, a tuple can consist of elements of multiple data types at the same time. You can create a tuple by placing all elements inside the parentheses(()) separated by commas.


1 Answers

Your first generator yields just once, and yields a tuple:

>>> gen = function_1(1, 2)
>>> gen = function_1(1, 2)
>>> next(gen)
(1, 2)
>>> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

The next() function takes the next value from an iterator (a generator is a specific type of iterator), if available. The StopIteration exception shows the generator is done and cannot produce more values.

Your second generator yields two separate times, each an integer:

>>> gen = function_2(1, 2)
>>> next(gen)
1
>>> next(gen)
2
>>> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Calling tuple() on a generator will pull in all values the generator produces, so for function_1 you'll get a tuple with one element, another tuple. For the second generator you'll get a tuple with two elements, the two integers. Compare that to using list() on the two generators:

>>> list(function_1(1, 2))
[(1, 2)]
>>> list(function_2(1, 2))
[1, 2]

Now we have two lists, but the first contains just one element, a tuple, because that is all that the generator produced.

As such, the two generators have fundamentally different behaviour. Pick the behaviour you need; either yield complete tuples, or yield separate values, but don't try and treat the two types of output as the same thing.

like image 83
Martijn Pieters Avatar answered Sep 24 '22 23:09

Martijn Pieters