The python function gives a tuple and only one element is required

I have a function

def f(): # whatever yield (a,b) 

Now I would like to collect all a , but not b . I also want the result aa be a list instead of an iterator. I'm using right now

 aa, _ = zip(*f()) 

Is this the best thing that can be done in terms of space / time efficiency?

+5
source share
5 answers

zip(*seq) must swallow the entire generator before it can output columns. It is not effective.

Just keep an understanding of the list. You can use tuple assignment:

 aa = [a for a, _ in f()] 

or use indexing:

 aa = [tup[0] for tup in f()] 

If you do not need to have all the values ​​for random access or other operations that a list should have, you can use a generator expression to maintain memory efficiency:

 aa = (a for a, _ in f()) 
+8
source

You can use a list comprehension that captures the first returned item

 aa = [result[0] for result in f()] 
+4
source

You cannot force it to yield only to one element of the tuple without changing f . However, you can easily generate generators, for example, using a generator expression:

 just_a_please = (a for a,b in f()) 

To consume all a with one hit, you should prefer a list comprehension:

 all_a = [a for a,b in f()] 

If you need only one of them, there is next :

 give_me_an_a, _b = next(f()) 
+3
source

just, you can use a list to get a list with the whole thing

 aa = [ a for a,_ in f() ] 
+1
source

To solve using the operator module:

 from operator import itemgetter get_first = itemgetter(0) aa = [get_first(x) for x in f()] 

Edit: I initially stated “for an efficient solution using the operator module”, but I cannot find any evidence that it is more efficient than the standard list comprehension approach.

Some anecdotal observations of %timeit :

 def f(): for i in xrange(0, 10000): yield (i, i ** i) def operator_way(): return [get_first(x) for x in f()] def tuple_unpack_way(): return [a for a, _ in f()] def indexing_way(): return [a[0] for a in f()] def map_way(): return map(get_first, f()) 

 %timeit operator_way() # 100 loops, best of 3: 9.25 ms per loop 

 %timeit tuple_unpack_way() # 100 loops, best of 3: 9.28 ms per loop 

 %timeit indexing_way() # 100 loops, best of 3: 9.17 ms per loop 

 %timeit map_way() # 100 loops, best of 3: 9.07 ms per loop 

They seem more or less equivalent. A map may be a little more efficient.

0
source

Source: https://habr.com/ru/post/1261022/


All Articles