Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to divide a tuple into two in pythonic way

I got a problem which is: receive a tuple with objects of any type, and separate it into two tuples: the first, with strings only; the second, with numbers only.

Alright. The standard algorithm would be something like:

def separate(input_tuple):
    return_tuple = ([],[])
    for value in input_tuple:
        if isinstance(value, str):
            return_tuple[0].append(value)
        if isinstance(value, numbers.Number):
            return_tuple[1].append(value)
    return tuple([tuple(l) for l in return_tuple])

That way, we only iterate once.

My question is: is there a way to do it in a more pythonic way? A one-liner?

I have tried

( tuple([i for i in input_tuple if isinstance(i,str)]), tuple([i for i in input_tuple if isinstance(i,numbers.Number)]))

But it is less efficient, as we iterate over the input tuple twice.

Also,

tuple([ tuple( [i for i in input_tuple if isinstance(i, k)]) for k in ((float ,int,complex), str) ])

Has the same problem, as we do two iterations. Would that be possible to iterate only once and still get the result, or because i am dealing with separation into two tuples, it isn't possible?

Thanks!

like image 886
rafaelc Avatar asked Apr 30 '15 23:04

rafaelc


1 Answers

I suppose you could do something like

my_tuple = ([],[])
for x in a_list:
   my_tuple[isinstance(x,basestring)].append(x) 

That would make it a little more pythonic I guess ... and still pretty readable.

Of course you could also put it in a list comprehension but not a great one:

[my_tuple[isinstance(x,basestring)].append(x) for x in a_list]

The list comprehension just gets tossed away and its basically being abused into a for loop.

like image 70
Joran Beasley Avatar answered Sep 28 '22 05:09

Joran Beasley