2009-11-23 3 views
27

У меня есть следующий код:Умножив кортеж скаляром

print img.size 
print 10 * img.size 

отпечатывается

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

в то время как я хотел бы, чтобы напечатать

(700, 700) 

Есть ли способ необходимо сделать это без необходимости писать

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

PS: img.size - изображение PIL. Не знаю, если это имеет значение в этом случае.

+3

Что случилось с '(10 * img.size [0], 10 * IMG. размер [1]) '? Я не понимаю, почему вам нужно переопределить что-то столь же простое, как умножение на 2 целых числа. Обратите внимание, что в этом кортеже всегда будет только два элемента! – paprika

+7

Я не переоцениваю. Я спрашиваю, есть ли более приятный и простой способ. Читайте мой пост снова. –

+3

@paprika: ... потому что этот кортеж может не иметь известной длины. В этом случае он (как и в случае, который привел меня к этому вопросу), но кодировал предполагаемую длину кортежа, повторяя скалярные * n * раз, и для того, чтобы получить индексы * n *, достаточно, чтобы избежать если это возможно. – J0e3gan

ответ

32

Может быть лучше так, но это должно работать

tuple([10*x for x in img.size]) 
+12

Немного приятнее: 'tuple (10 * x для x в img.size)' – Vegard

+0

https://stackoverflow.com/a/48351745/500902 приятнее. Сам Пац на спине. – Marvin

1

Вы можете попробовать что-то вроде этого:

print [10 * s for s in img.size] 

Это даст вам новый список со всеми элементами вы имеете в тупл умноженный на 10

13

вещих образом будет использовать список понимание:

y = tuple([z * 10 for z in img.size]) 

Другой способ может быть:

y = tuple(map((10).__mul__, img.size)) 
+0

Эта вторая потрясающая ... ха-ха. –

+2

Ни один из примеров не отражает точку вопроса. Оба заставляют программиста взять простую идею (умножить матричное умножение) и деконструировать ее. –

3

Существует, вероятно, более простым способом, чем это, но

print map(lambda x: 10*x, img.size) 

будет делать почти то, что вы хотите, хотя он печатает как вместо кортежа. Обмотайте вызов map внутри tuple(map...), если вы хотите, чтобы он печатался как кортеж (скобки, а не квадратные скобки).

2

Если у вас есть эта проблема чаще и с большими кортежами или списками, вы можете использовать библиотеку numpy, которая позволяет выполнять все виды математических операций на массивах. Однако в этой простой ситуации это было бы полным перегибом.

+0

Хотя для * простого * примера было бы излишним использовать numpy, точка вопроса, похоже, «Предлагает ли python способ, который выполняет mimic-операции, просто выражается в математике?» Я имею в виду, если у вас есть матрица A = [70 70], тогда 2A = [140 140]. –

0

не добавляя ничего, кроме разнообразия ..

import operator 
img_size = (70, 70) 
map(operator.mul, img_size, len(img_size)*(10,)) 
6

Решение:

set1=(70, 70) 
tuple(2*array(set1)) 

Объяснение: arrays делают возможным прямое умножение. Следовательно, tuple, называемый здесь set1, преобразуется в array. Я предполагаю, что вы хотите продолжать использовать tuple, поэтому мы преобразуем array обратно в tuple.

Это решение должно избегать явного и подробного цикла for. Я не знаю, быстрее ли это или происходит то же самое в обоих случаях.

+1

Это не работает в Python 2 или 3, насколько я могу судить. Я предполагаю, что 'array' происходит от модуля' array'? Python ожидает, что символ будет первым аргументом для 'array', поэтому передача только кортежа in приведет к ошибке с аргументом TypeError: array() 1 или typecode должен быть char (строка или ascii-unicode с длиной 1), а не tuple'. Можете ли вы расширить это с помощью более полного примера? – Kumba

1

В соответствии с предыдущими ответами, но с использованием NumPy:

import numpy as np 
result = tuple(10*np.array(img.size)) 
0

Вы пытаетесь применить функцию кортежей в целом. Вам необходимо применить его к отдельным элементам и вернуть новый кортеж.

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

Помните, что вы не можете изменить Кортеж.

0

Simplish вещь, если вы пишете кучу кода, но не хотите более сложный вектор библиотеки ...

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) 

«V» экземпляры иначе ведут себя так же, как кортежей. Это требует, чтобы экземпляры «V» были созданы с одинаковым количеством элементов. Можно добавить, например, __new__

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

для обеспечения, что все экземпляры 2d векторов ....

Смежные вопросы