Gå til innhold

Anbefalte innlegg

Jeg har en lang liste med tekst og nummer. Hver linjer ser slik ut:

"Dette er linje 1, 42.32"
"Dette er linje 2, 42.43"
"Dette er linje 3, 34.744"
"Dette er linje 4, 34.12" 

osv..

 

Linjene består av tekst i starten, og nummer i slutten separert av komma, for at jeg lett kan skille dem slik:

line = "Dette er linje 1, 42.32"
text, num = line.split(',')

Koden går som følger.

1. Jeg lager en dictionary

2. Jeg går gjennom linje for linje, plukker ut det første nummerer (første nummeret vil da si det første nummeret av "42.32", som er 42)
a. Jeg lagrer første linje under key["42"] i en liste.
b. Jeg går gjennom andre linje og lagrer også den under key["42"] i samme liste.
c. Jeg lagrer den 3. linjen i under en ny key, altså key["34"] i en ny liste
osv..

Nå står jeg igjen med 10-30 linjer under hver key. Jeg ønsker deretter å sortere hver eneste linje, under hver key, etter det andre nummeret (andre nummer av "42.32" blir da 32), slik at de havner i stigende rekkefølge.

 

Problemet er at jeg lett kan plukke ut det andre nummeret for så å sortere alt sammen, men hvordan skal jeg da hvite hvilken linje som hører til hvilket tall, og enda verre, hva om det andre nummeret er likt på flere linjer?

 

Spørmålet ble nok ganske uoversiktelig, men håper dere skjønner det.

Kort forklaring:

tall = "42.32"

Det første tallet beskriver hvilken "mappe"(dict) den skal plasseres i.
Det andre tallet vil jeg sortere i stigende rekkefølge.

Problem: Sliter med å sortere hver linje etter det siste tallet, samtidig som jeg vet hvilken linje(tekst og tall) det er snakk om.

 

EDIT: I dette tilfellet, hvilken måte er mest effektiv, raskest og best å bruke til å sortere linjene med?

Håper noen kan hjelpe

 

-Daniel

Endret av Axxxy
Lenke til kommentar
Videoannonse
Annonse

Om jeg forstår riktig, så gjør den jobben med sorteringen. Men hvordan skal jeg linke teksten til tallene igjen?

Filen med alle disse linjene er usortert, jeg vil gjerne sortere hver linje etter de to tallene på samme måte som du beskriver, men hvordan skal jeg vite hvilken linje som hører til hvilken tekst?

lst = ["Dette er linje 1, 42.32",
       "Dette er linje 2, 42.43",
       "Dette er linje 3, 34.744",
       "Dette er linje 4, 34.12" ]
lst1 = []
for i in lst:
    num = i.split(',')[-1].strip()
    num1, num2 = num.split('.')
    tup = (num1, num2)
    lst1.append(tup)

for i in lst1:
    print i

>>>('42', '32')
>>>('42', '43')
>>>('34', '744')
>>>('34', '12')

lst1.sort()

>>>('34', '12')
>>>('34', '744')
>>>('42', '32')
>>>('42', '43')

-Daniel

Endret av Axxxy
Lenke til kommentar

Python kan sortere på doubles, så bare lag en tuple (number, text) og sorter som vanlig. Da vil de være sortert etter numrene, og de vil alltid ligge sammen med tekstlinjen.

 

def line_to_tuple( line ):
    txt, num = line.split( ',' )
    return ( double( num ), txt )

with open( "file", "r" ) as txt:
    list = map( line_to_tuple, txt )

list.sort()
Endret av Lycantrophe
Lenke til kommentar

Orket ikke lese hele første posten, da den var smått forvirrende.. Så jeg gjetter..

lst = ["Dette er linje 1, 42.32",
       "Dette er linje 2, 42.43",
       "Dette er linje 3, 34.744",
       "Dette er linje 4, 34.12" ]


data = [l.split(',') for l in lst]
data.sort(key=lambda x: float(x[1]));
print [(',').join(l) for l in data]

>> ['Dette er linje 4, 34.12', 
    'Dette er linje 3, 34.744', 
    'Dette er linje 1, 42.32', 
    'Dette er linje 2, 42.43']


# Alternativ
# Det er nok mere effektivt å endre til float før vi sorterer (ferre casts)..
# 
cast = lambda k: (k[0],float(k[1]))  
data = [cast(l.split(',')) for l in lst]
data.sort(key=lambda x: x[1]);

merge = lambda x,glue: x[0] + glue + str(x[1]);
print [merge(l,', ') for l in data]
>> ['Dette er linje 4, 34.12', 
    'Dette er linje 3, 34.744', 
    'Dette er linje 1, 42.32', 
    'Dette er linje 2, 42.43']
Endret av warpie
Lenke til kommentar
input =
["Dette er linje 1, 42.32",
"Dette er linje 2, 42.43",
"Dette er linje 3, 34.744",
"Dette er linje 4, 34.12"]

output =
["Dette er linje 4,  34.12",
"Dette er linje 3,  34.744",
"Dette er linje 1,  42.32",
"Dette er linje 2,  42.43"]


def sort0(lst):
    #Min (inspirasjon fra Lycantrophe), uten float converion
    lst2 = []
    for i in lst:
        text, num = i.split(',')
        tup = (num, text)
        lst2.append(tup)
    lst2.sort()
    final = []
    for i in lst2:
        i = list(i)
        i.reverse()
        final.append(', '.join(i))

def sort0(lst):
    #Min (inspirasjon fra Lycantrophe), med float conversion
        lst2 = []
    for i in lst:
        text, num = i.split(',')
        num = float(num)
        tup = (num, text)
        lst2.append(tup)
    lst2.sort()
    lst3 = []
    for i in lst2:
        i = list(i)
        i.reverse()
        i[-1] = str(i[-1])
        lst3.append(', '.join(i))
    final = lst3

def sort2(lst):
    #warpie sitt første eksempel
    data = [l.split(',') for l in lst]
    data.sort(key=lambda x: float(x[1]));
    final = [(',').join(l) for l in data]

def sort3(lst):
    #warpie sitt andre eksempel
    cast = lambda k: (k[0],float(k[1]))
    data = [cast(l.split(',')) for l in lst]
    data.sort(key=lambda x: x[1]);
    merge = lambda x,glue: x[0] + glue + str(x[1]);
    final = [merge(l,', ') for l in data]

## Gjennomsnitt av timeit 5 ganger
timeit.timeit(sort0, number=100000)
>>> 3.34768958568
timeit.timeit(sort1, number=100000)
>>> 5.37434810849
timeit.timeit(sort2, number=100000)
>>> 2.86074032834
timeit.timeit(sort3, number=100000)
>>> 5.00445209583

Takk for alle forslag

Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...