Multiplying a tuple by a scalar

Viewed 93740

I have the following code:

print(img.size)
print(10 * img.size)

This will print:

(70, 70)
(70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70)

I'd like it to print:

(700, 700)

Is there any way to do this without having to write:

print(10 * img.size[0], 10 * img.size[1])

PS: img.size is a PIL image. I don't know if that matters anything in this case.

12 Answers

Simplish thing if you're writing a bunch of code, but don't want a more complicated vector library...

class V(tuple):
    '''A simple vector supporting scalar multiply and vector add'''
    def __new__ (cls, *args):
        return super(V, cls).__new__(cls, args)
    def __mul__(self,s):
        return V( *( c*s for c in self) )
    def __add__(self,s):
        return V( *( c[0]+c[1] for c in zip(self,s)) )
    def __repr__(self):
        return "V" + super(V, self).__repr__()

# As long as the "vector" is on the left it just works

xaxis = V(1.0, 0.0)
yaxis = V(0.0, 1.0)
print xaxis + yaxis      # => V(1.0, 1.0)
print xaxis*3 + yaxis*5  # => V(3.0, 5.0)
print 3*xaxis            # Broke, => (1.0, 0.0, 1.0, 0.0, 1.0, 0.0)

The "V" instances otherwise behave just like tuples. This requires that the "V" instances are all created with the same number of elements. You could add, for example, to __new__

if len(args)!=2: raise TypeError('Must be 2 elements')

to enforce that all the instances are 2d vectors....

Just to overview

import timeit

# tuple element wise operations multiplication

# native
map_lambda = """
a = tuple(range(10000))
b = tuple(map(lambda x: x * 2, a))
"""

# native
tuple_comprehension = """
a = tuple(range(10000))
b = tuple(x * 2 for x in a)
"""

# numpy
using_numpy = """
import numpy as np
a = tuple(range(10000))
b = tuple((np.array(a) * 2).tolist())
"""

print('map_lambda =', timeit.timeit(map_lambda, number=1000))
print('tuple_comprehension =', timeit.timeit(tuple_comprehension, number=1000))
print('using_numpy =', timeit.timeit(using_numpy, number=1000))

Timings on my machine

map_lambda = 1.541315148000649
tuple_comprehension = 1.0838452139996662
using_numpy = 1.2488984129995515

You are trying to apply the function on Tuple as a whole. You need to apply it on individual elements and return a new tuple.

newTuple = tuple([10*x for x in oldTuple])

Remember you cannot change a Tuple.

Related