2009-11-23 15 views
27

Mam następujący kod:Mnożąc krotki przez skalar

print img.size 
print 10 * img.size 

to wypisze

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

natomiast chciałbym go wydrukować

(700, 700) 

jakikolwiek sposób Aby to zrobić, nie trzeba pisać:

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

PS: img.size to obraz PIL. Dunno, jeśli to ma znaczenie w tym przypadku.

+3

Co z '(10 * img.size [0] 10 * img. rozmiar [1]) "? Nie rozumiem, dlaczego musisz przesadzać z czymś tak prostym jak mnożenie 2 liczb całkowitych. Zauważ, że ta krotka zawsze będzie zawierała tylko dwa elementy! – paprika

+7

Nie prześladuję. Pytam, czy istnieje lepszy, prostszy sposób. Przeczytaj mój post ponownie. –

+3

@paprika: ... ponieważ dana krotka może nie mieć znanej długości. W tym przypadku robi (tak jak w przypadku, który doprowadził mnie do tego pytania), ale kodowanie dla przyjętej długości krotki, powtarzanie skalarne * n * razy i posiadanie współczynnika * n * indeksów jest wystarczająco kludgy, aby uniknąć jeśli to możliwe. – J0e3gan

Odpowiedz

32

Może być milszy sposób, ale to powinno działać

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

Nieco ładniejsza: 'krotka (10 * x za x w img.size)' – Vegard

+0

https://stackoverflow.com/a/48351745/500902 jest ładniejsza. Pats sam z tyłu. – Marvin

1

Można spróbować czegoś takiego:

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

To da ci nową listę wszystkich elementów zapisanych w krotka pomnożona przez 10

13

pythonic sposobem byłoby używając wyrażeń listowych:

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

Innym sposobem może być:

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

Ten drugi jest niesamowity ... haha. –

+2

Żaden z przykładów nie przechwytuje punktu pytania. Zarówno zmuszają programistę do podjęcia prostego pomysłu (mnożenie macierzy razy iloczyn skalarny) i jego dekonstrukcji. –

24
img.size = tuple(i * 10 for i in img.size) 
3

Jest prawdopodobnie prostszy sposób niż ten, ale

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

Zrobi prawie co chcesz, choć drukuje jako lista zamiast krotki. Zawiń wywołanie map wewnątrz tuple(map...), jeśli chcesz, aby był drukowany jako krotka (nawiasy zamiast nawiasów kwadratowych).

2

Jeśli masz ten problem częściej i z większymi krotkami lub listami, możesz użyć biblioteki numpy, która pozwala wykonywać wszystkie rodzaje operacji matematycznych na tablicach. Jednak w tej prostej sytuacji byłaby to zupełna przesada.

+0

Podczas gdy dla * prostego * przykładu może to być przesada, aby użyć numpy, pytanie brzmi: "Czy python oferuje sposób w jaki operacje naśladujące mogą być po prostu wyrażane w matematyce?" Mam na myśli, jeśli macie macierz A = [70 70], a następnie 2A = [140 140]. –

0

dodając nic prócz różnych ..

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

Rozwiązanie:

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

Objaśnienie: arrays dokonać bezpośredniego mnożenie przez skalar możliwe. W związku z tym tuple o nazwie set1 tutaj jest konwertowane na array. Zakładam, że chcesz nadal używać tuple, dlatego konwertujemy array z powrotem na tuple.

Rozwiązanie to polega na uniknięciu jawnej i pełnej informacji pętli for. Nie wiem, czy jest to szybsze, czy też dokładnie to samo dzieje się w obu przypadkach.

+1

To nie działa w Pythonie 2 lub 3, o ile wiem. Zakładam, że 'tablica' pochodzi z modułu' tablica'? Python oczekuje, że znak będzie pierwszym argumentem dla 'tablica', dlatego przekazanie tylko krotki zakończy się niepowodzeniem z argumentem TypeError: array() 1 lub kod typowy musi być char (łańcuch lub ascii-unicode o długości 1), a nie krotka. Czy możesz rozwinąć ten temat za pomocą pełniejszego przykładu? – Kumba

1

Zgodnie z poprzednich odpowiedzi, ale przy użyciu numpy:

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

Próbujesz zastosować funkcję na krotki jako całości. Musisz zastosować go na poszczególnych elementach i zwrócić nową krotkę.

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

Pamiętaj, że nie możesz zmienić krotki.

0

Simplish rzeczą jeśli piszesz pęczku kodu, ale nie chcą bardziej skomplikowanej biblioteki wektor ...

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” przypadki inaczej zachowują się podobnie jak krotki. Wymaga to, aby instancje "V" były tworzone z taką samą liczbą elementów. Można dodać, na przykład, do __new__

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

wymusić, że wszystkie przypadki są 2d wektory ....