array multisort?

D
  • 9 Grd '07

kaip python vienu metu rikiuoti kelis susietus masyvus?
gal netyčia yra kažkas pan kaip http://php.net/array_multisort ?

mano variantas, pasiskaičius http://wiki.python.org/moin/HowTo/Sorting

maistas = ['apple', 'carrot', 'apple', 'bread']
kiekis = [5, 8, 3,11]
valgytojas = [u'kiaulė', u'karvė', u'triušis', u'Petras']

norim surikiuot pagal maistą ir kiekį

arr = zip(maistas, kiekis, valgytojas) # surišu reikšmes
arr.sort() #pagal vieną pirmąjį lauką rikiuot baikos
import operator
arr.sort(key=operator.itemgetter(1)) #pagal vien tik antrąjį irgi nesunku (1 reiškia antrą poziciją, nes numeruojama nuo 0)

o kad pagal pirmą ir antrą iš kart

reik pasirašyti funkciją

def mycmp(x, y):
if x[0]<y[0]: return -1; #pagal pirmą
if x[0]==y[0]:
if x[1]<y[1]: return -1; #jei pirmi lygūs, rūšiuot pagal antrą
return 0

arr.sort(key=operator.itemgetter(2)) #dar sumaišom, kad nuo ankstesnių rūšiavimų neliktų įtarimų

arr.sort(cmp=mycmp)

o kad susigrąžint nepriklausomus masyvus:

maistas, kiekis, valgytojas = zip(*arr) #čia ne iš kart supratau gudrybę, bet šiaip patogu atsimint transponavimui

D
  • 9 Grd '07

ups, matau atitraukimo nuo krašto nesimato html'e, tai "mycmp" nekorektiškai atrodo... tiems kas aklai copypastins

0
  • 24 Vas '09

Arba as cia kazka supainiojau arba yra daug paprasciau .
T.y. jei turi laukus A,B,C ir nori isrusiuoti is pradziu pagal A, paskui pagal B, paskui pagal C ir t.t. Tai ta padaryt gana paprasta:

from random import *
def rlist(): return [randint(1,6) for x in range(10)]
for x in sorted(zip(rlist(),rlist(),rlist())):print x

Gaunu mazdaug toki vaizda:
...
(1, 1, 2)
(1, 3, 2)
(3, 1, 4)
(3, 4, 5)
(4, 1, 2)
(5, 1, 2)
(5, 2, 6)
(5, 3, 1)
(5, 3, 5)
(6, 2, 3)

Tai gal cia tai ko tu nori ? Pointas- naudoti sorted() funkcija.
Problemos nebent butu jei rusiavimo tvarka kitokia, jei lauku eiliskumas, t.y. sakykim norim rusiuoti pagal B, paskui pagal A, paskui pagal C. Na tokiam atvejui tada kaip ir tu rasei ko gero reiks rasyti palyginimo (cmp) funkcijas (arba naudoti lambda).