Kry
Kry

Reputation: 11

Cast tuples inside list to int

How would one go about turning a list with tuples inside it, in the form of,

list = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]

into a list with ints in it, like,

list = [197, 156, 17, 14, 74, 7]

in the most efficient way possible? I've tried with recursion but it's too memory expensive for large lists (thousands of tuples).

Upvotes: 1

Views: 273

Answers (4)

Moinuddin Quadri
Moinuddin Quadri

Reputation: 48077

You may also use little bit of mathematics to achieve this. Here I am multiplying the digits in tuple with power of 10 in reverse order to get the number.

>>> my_list = list = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]

#     v sum numbers based on their position at hundred, tens, ones place  
>>> [sum(t[-i-1]*(10**i) for i in range(len(t))) for t in my_list]
[197, 156, 17, 14, 74, 7]

Upvotes: 0

niemmi
niemmi

Reputation: 17263

You could use functools.reduce for converting every tuple:

>>> from functools import reduce
>>> l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]
>>> [reduce(lambda x,y: x*10+y, t) for t in l]
[197, 156, 17, 14, 74, 7]

Update Since question was asking for efficient method here are measurements for suggested answers:

import itertools as it
import functools

def conv_reduce(l):
    return [functools.reduce(lambda x,y: x*10+y, t) for t in l]

def conv_str(l):
    return [int("".join(map(str, item))) for item in l]

def conv_pow(l):
    return [sum(n*10**e for n, e in zip(reversed(item), it.count())) for item in l]

def conv_pow2(l):
    return [sum(t[-i-1]*(10**i) for i in range(len(t))) for t in l]

if __name__ == '__main__':
    import timeit
    print('reduce', timeit.timeit("conv_reduce(l)", setup="from __main__ import conv_reduce; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))
    print('str', timeit.timeit("conv_str(l)", setup="from __main__ import conv_str; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))
    print('pow', timeit.timeit("conv_pow(l)", setup="from __main__ import conv_pow; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))
    print('pow2', timeit.timeit("conv_pow2(l)", setup="from __main__ import conv_pow2; l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]"))

Output:

reduce 2.5965667460041004
str 5.068828338997264
pow 7.192991987001733
pow2 8.017168823003885

Upvotes: 4

AChampion
AChampion

Reputation: 30258

It's relatively simple to convert a list of digits to a number. Convert them to strings join() and convert back to int. Or you can do it more mathematically:

>>> [sum(n*10**e for e, n in enumerate(reversed(item))) for item in l]
[197, 156, 17, 14, 74, 7]

Note: don't use list as a variable name as this will hide the python list type.

Upvotes: 1

alecxe
alecxe

Reputation: 473873

One way to approach the problem is to cast to string each of the integers in sublists, join and convert to int:

In [1]: l = [(1, 9, 7), (1, 5, 6), (1, 7), (1, 4), (7, 4), (7,)]

In [2]: [int("".join(map(str, item))) for item in l]
Out[2]: [197, 156, 17, 14, 74, 7]

Or, using the power of tens (a variation of already posted answer by @AChampion):

In [3]: [sum(10 ** index * value for index, value in enumerate(reversed(item))) 
         for item in l]
Out[3]: [197, 156, 17, 14, 74, 7]

Upvotes: 2

Related Questions