PDA

Prikaži potpunu verziju : python tuple pitanjce


orange47
19.6.2013, 8:29
kako da pretvorim ovaj tuple:
[(1,1,aa), (1,1,ab), (1,2,ac), (1,2,ad), (1,2,ad), (1,3,ae), (1,3,ag), (2,1,ah)]

u ovo:

([[aa,ab], [ac,ad,ad], [ae,ag]], [[ah]])


?

hvala.

ivan90BG
23.6.2013, 0:13
Glavno pitanje ovde je u kakvom scenariju će se ova transformacija odvijati i da li se to može rešiti na drugačiji način? Tuples (po srpski n-torke) u Pythonu su nepromenljivi objekti (nema dodavanja ni menjanja elemenata). Čini mi se da ti prva cifra označa poziciju na prvom nivou ugnježdenja, a druga poziciju na drugom. Pošto prva cifra ozačava poziciju unutar tupla ova transformacija ne može da se izvede jer nije moguće napraviti tuple čija se veličina nalazi kao broj zapisan u nekoj promenljivoj. Tuple se kreira sintaksom sa zagradama i elementima odvojenim zarezima (time tuple dobija veličinu i elemente) i više se ne može izmeniti (može se samo nenjati sadržaj njegovih elementata, ako to dozvoljavaju).

Stevvan
23.6.2013, 16:45
Pretpostavljam da za ulaz tih elemenata treba da dobijes izlaz koji si naveo :) Sve se moze kad se hoce, samo objasni koja je tacno logika smestanja elemenata, tj sta tacno hoces da uradis? Delovalo mi je kao da ovi brojevi govore poziciju ali nije tako, znaci samo objasni sta pokusavas tj koja je logika pa ti mozda mogu pomoci.

M.Silenus
23.6.2013, 17:25
Ovako nešto?


input = [(1,1,'aa'), (1,1,'ab'), (1,2,'ac'), (1,2,'ad'), (1,2,'ad'), (1,3,'ae'), (1,3,'ag'), (2,1,'ah')]

# ocekivan rezultat
'''
{
1: [(1, 'aa'), (1,'ab'), (2, 'ac'), (2, 'ad'), (2, 'ad'), (3, 'ae'), (3, 'ag')]
2: [(1, 'ah')]
}
'''
ds = {}

for i in input:
if i[0] not in ds:
ds[i[0]] = [ (i[1], i[2]) ]
else:
ds[i[0]].append((i[1], i[2]))

# dalje:
'''
{
1: { 1: ['aa', 'ab'], 2:['ac', 'ad', 'ad'], 3: ['ae', 'ag'] }
2: { 1: ['ah'] }
}
'''
# odakle dobijamo rezultat

output = []

for d in ds:
tmp = {}
for el in ds[d]:
if el[0] not in tmp:
tmp[el[0]] = [el[1]]
else:
tmp[el[0]].append(el[1])
output.append(tmp.values())

print tuple(output)


Ne naročito efikasno rešenje, ali urađeno za 10 minuta.
Inače, možeš da konstruišeš drvo, pa da ga pretvoriš u listu (trebalo bi da je prilično pravolinijski, samo ima malo da se kuca).

seymourc64
26.6.2013, 13:37
Nisam odmah shvatio da treba praviti nizove i po redovima i po kolonama. Evo mog resenja, koje je dosta slicno prethodnom. Oba resenja koriste dictionary za grupisanje


#!/usr/local/bin/python2.7
origList = [(1,1,'aa'), (1,1,'ab'), (1,2,'ac'), (1,2,'ad'), (1,2,'ad'), (1,3,'ae'), (1,3,'ag'), (2,1,'ah')]
translateDict = {}
for row,col,val in origList:
if row not in translateDict:
translateDict[row] = {col : []}
if col not in translateDict[row]:
translateDict[row][col] = []
translateDict[row][col].append(val)

finalList = [[translateDict[i][j] for j in translateDict[i]] for i in translateDict]

print tuple(finalList)


Ako za svaki slucaj zelis da ocuvas redosled po redovima i kolonama poslednju listu kreiraj sa

finalList = [[translateDict[i][j] for j in sorted(translateDict[i].iterkeys())] for i in sorted(translateDict.iterkeys())]

ice*91
5.7.2013, 15:47
Slucajno sam naleteo na temu i kontam da se kasno javljam, ali zapalo mi je za oko ovo trpanje u dictionary za sta mislim da je suvisno, u sustini deluje elegantno ali jednostavnije je odmah redeom stavljati elemente u listu i kasnije konvertovati u tuple ako se trazi...
recimo:

Ulaz = [(1,1,'aa'), (1,1,'ab'), (1,2,'ac'), (1,2,'ad'), (1,2,'ad'), (1,3,'ae'),(1,3,'ag'), (2,1,'ah')]
Lista = []
Predhodni = None
for Tuple in sorted(Ulaz): ##sorted funkcija je za slucaj kada Ulaz nije sortiran, inace moze samo Ulaz.
if Lista == [] or Tuple[0] > Predhodni[0] : Lista.append([])
if Lista[Tuple[0]-1] == [] or Tuple[1] > Predhodni[1] : Lista[Tuple[0]-1].append([])
Lista[Tuple[0]-1][Tuple[1]-1].append(Tuple[2])
Predhodni = Tuple
print tuple(Lista)

orange47
5.7.2013, 17:20
hvala svima.

prva brojka je oznaka 'nadgrupe' a druga podgrupe odnosno podskupa. bitno je da se treci element pravilno grupise, redosled nije bitan. mislio sam da ima neko sasvim jednostavno resenje.
ne mora da bude tuple, moze i lista.

orange47
9.7.2013, 11:34
hvala, odlicno radi ovo sa dict.
@ice*91
ne mogu da sortiram, jer ima raznih kombinacija.
@seymourc64
jel mozes molim te da promenis tako da radi sa elementima tipa: (1,1,'aa','bb') ? tako da razvrstava ['aa','bb'] po grupama
pokusao sam nesto, ali dobijem [['aa','bb']] umesto ['aa','bb']
edit: nema veze, resio sa 'extend' umesto 'append'

seymourc64
9.7.2013, 16:33
Ako se koristi lista, u ulazu moraju biti svi "redovi" i "kolone" redom popunjeni sto ne mora biti slucaj.

Evo primera koji radi sa tuplovima gde posle row, col ide N stringova.


for item in origList:
row = item[0]
col = item[1]
vals = item[2:]
if row not in translateDict:
translateDict[row] = {col : []}
if col not in translateDict[row]:
translateDict[row][col] = []
translateDict[row][col].extend(vals)


Ako koristis python 3+, mozes ona tri prva reda posle fora da zamenis sa(nisam proverio)

row, col, *vals = item


Edit: sada kontam zasto si napisao ovo sa extend i append :)