RolloThomasi Skrevet 8. november 2009 Del Skrevet 8. november 2009 (endret) Hallo! Har en liste av 2-tupler slik: list = [(x1, y1), (x2, y2), (x3, y3), ...] Jeg ønsker å få tak i alle x-verdiene og alle y-verdiene hver for seg. Det jeg har prøvd å gjøre er å slice slik: x = list[:][0]; y = list[:][1] men dette funker ikke i det hele tatt. Resultatet er som følger: list[:][0] == list[0][:] == list[0] == (x1, y1) Det er null problem å individuelt indeksere elementene slik som dette: list[0][0] == x1 list[1][0] == x2 Men indeksering vha. slicing er altså helt uaktuelt. Har dette å gjøre med at slicing lager en kopi? Kan noen være så vennlig å forklare hvorfor det er sånn? Eller har noen et tips om hvordan jeg kan omgå dette? (Python-llama'er vil vel kalle det en feature... ) For øyeblikket konverterer jeg til en numpy.ndarray og da får jeg gjort det jeg ønsker, men det kan vel ikke være nødvendig? på forhånd takk edit: Har nå mer eller mindre overbevist meg selv om at følgende skjer: Slicinga velger ut (evt. kopierer) hele lista av tupler, og så velges det ut en index i den nye lista. (Ingen errors selv om man skulle finne på å skrive list[:][:][:][:][0] resultatet er fremdeles lik list[0]). Dette er jo ganske inkonsistent oppførsel spør du meg. Pythonic is moronic Enten det, eller så har jeg blitt bortskjemt av arrayer og vektorisering etc i numpy. Endret 8. november 2009 av RolloThomasi Lenke til kommentar
zotbar1234 Skrevet 9. november 2009 Del Skrevet 9. november 2009 Har en liste av 2-tupler slik: list = [(x1, y1), (x2, y2), (x3, y3), ...]Jeg ønsker å få tak i alle x-verdiene og alle y-verdiene hver for seg. Det jeg har prøvd å gjøre er å slice slik: x = list[:][0]; y = list[:][1] men dette funker ikke i det hele tatt. Resultatet er som følger: list[:][0] == list[0][:] == list[0] == (x1, y1) Ja, siden l[:][0] betyr "ta en kopi av l (som blir en liste av par), ta deretter det 0-te elementet (som er det første paret i listen). variant 1: >>> l ((1, 2), (3, 4)) >>> list(itertools.starmap(lambda x, y: x, l)) [1, 3] variant 2: >>> from operator import itemgetter >>> map(itemgetter(0), l) [1, 3] variant 3: >>> [x[0] for x in l] Det er null problem å individuelt indeksere elementene slik som dette:list[0][0] == x1 list[1][0] == x2 Men indeksering vha. slicing er altså helt uaktuelt. Har dette å gjøre med at slicing lager en kopi? Nei, det har noe å gjøre med assosiativiteten til operatorne. l[:][0] betyr: ta en (shallow) kopi av l anvende deretter indekseringsoperatoren på kopien returner resultatet av indekseringsoperatoren. Det du ønsker å gjøre er å si "for hvert element i l, anvend indekseringsoperatoren, og deretter akkumuler resultatene i en ny liste". List comprehension er kanskje det enkleste som oppnår det du vil. starmap og itemgetter er litt iteratorpornografi (godt kjent for C++-brukere), men virker i en mer generell setting. Kan noen være så vennlig å forklare hvorfor det er sånn? Eller har noen et tips om hvordan jeg kan omgå dette? (Python-llama'er vil vel kalle det en feature... ) Vel, jeg tror ikke din misforståelse av semantikken til slice/indeks-operatorne i Python er en feature av Python. For øyeblikket konverterer jeg til en numpy.ndarray og da får jeg gjort det jeg ønsker, men det kan vel ikke være nødvendig? Hvis det er store numeriske oppgaver du skal gjøre, er det kanskje greit å forbli venner med numpy? Litt andre designmål der, og litt mer egnet for tallprosessering enn Python sine lister. edit:Har nå mer eller mindre overbevist meg selv om at følgende skjer: Slicinga velger ut (evt. kopierer) hele lista av tupler, og så velges det ut en index i den nye lista. (Ingen errors selv om man skulle finne på å skrive list[:][:][:][:][0] resultatet er fremdeles lik list[0]). Operatorassosiativitet er tipset her. Dette er jo ganske inkonsistent oppførsel spør du meg. Pythonic is moronic Enten det, eller så har jeg blitt bortskjemt av arrayer og vektorisering etc i numpy. Eller så har du ikke forstått hvordan operatorne virker i Python. Lenke til kommentar
asicman Skrevet 7. januar 2010 Del Skrevet 7. januar 2010 Eller har noen et tips om hvordan jeg kan omgå dette? Du kan bruke map for å iterere over en liste: map(lambda l: l[0],list) ; gir deg første element i hver tuple map(lambda l: l[-1],list) ; gir deg siste element i hver tuple Du sier ikke noe om hvordan du vil bruke dem videre. Lenke til kommentar
RolloThomasi Skrevet 26. februar 2010 Forfatter Del Skrevet 26. februar 2010 Her var det kommer noen svar ja, kan ikke minnes å ha fått noe varsel. Takk for svar Zotbar1234 (og asicman), veldig utdypende og forklarende, men du trenger ikke ta min frustrasjon personlig Hadde det nå ennå vært lov å override assosiativosv ved hjelp av parenteser skulle jeg ikke sagt noe. Man kan vel neppe regne med å være 100% fornøyd når man lærer seg et nytt språk, men Python kommer definitivt svært nære. Lenke til kommentar
zotbar1234 Skrevet 2. mars 2010 Del Skrevet 2. mars 2010 Hadde det nå ennå vært lov å override assosiativosv ved hjelp av parenteser skulle jeg ikke sagt noe. For det første, hva betyr "override assosiativitet"? For det andre, dersom du mener at du ønsker å bruker parenteser for å endre assosiativitet, så er dette trivielt: >>> (1 - (2 - (3 - 4))) -2 >>> ((1 - 2) - 3) - 4 -8 Sist, men aller viktigst, problemet er/var at du misforstod betydningen av slicing-operatoren. Det kan ikke rettes med parentesomrokkering. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå