2017-01-25 2 views
0

Hallo Ich habe komplizierte Datenobjekte, die ich durch s sortieren möchte. Vereinfachte Version unten:Sortierung der Liste mit bestimmten Regeln

class Data(object): 
    def __init__(self, s): 
     self.s = s 

Jedes dieser Datenobjekte wird in eine bestimmte Kategorie platziert, um es später zu verwenden. Vereinfachte Version wieder unter

Ich möchte Daten nach unten durch ihre s-Nummer sortieren ABER Es gibt ein paar mehr Regeln. Wenn ein Datenobjekt von der ersten Datensammlung verwendet wurde, möchte ich eines aus der zweiten Sammlung verwenden, wenn die Nummer der Nummer gleich oder niedriger ist. Hier ist, was ich und was will ich

# order I get 
# [['p02g01r05', 5], ['p02g01r01', 4], ['p01g01r05', 4], ['p01g01r01', 3], ['p01g01r02', 2], ['p01g01r03', 2], ['p01g01r06', 2], ['p02g01r02', 2], ['p02g01r03', 2], ['p02g01r04', 2], ['p01g01r04', 1], ['p02g01r06', 1]] 
# order I want 
# [['p02g01r05', 5], ['p01g01r05', 4], ['p02g01r01', 4], ['p01g01r01', 3], ['p02g01r02', 2], ['p01g01r02', 2], ['p02g01r03', 2], ['p01g01r03', 2], ['p02g01r04', 2], ['p01g01r06', 2], ['p02g01r06', 1]], ['p01g01r04', 1] 

Dies ist zu erreichen, was ich bisher erschaffen, aber ich denke, dass ich mit diesem in die falsche Richtung gehe. Die Liste der zu ersetzenden Indizes ist korrekt, denke ich.

# Some data objects 
p01g01r01 = Data(3) 
p01g01r02 = Data(2) 
p01g01r03 = Data(2) 
p01g01r04 = Data(1) 
p01g01r05 = Data(4) 
p01g01r06 = Data(2) 

p02g01r01 = Data(4) 
p02g01r02 = Data(2) 
p02g01r03 = Data(2) 
p02g01r04 = Data(2) 
p02g01r05 = Data(5) 
p02g01r06 = Data(1) 

p01g01 = DataCategory("01", "01", []) 
p02g01 = DataCategory("02", "01", []) 


# link data to data category 
def ldtdc(dc): 
    lst = [] 
    data = "p" + dc.id1 + "g" + dc.id2 + "r" 
    for i in range(1, 7): 
     if i < 10: 
      lst.append(data + "0" + str(i)) 
     else: 
      lst.append(data + str(i)) 
    return lst 

p01g01.ld = ldtdc(p01g01) 
p02g01.ld = ldtdc(p02g01) 


# /@= This starts to get way too complicated fast ############################ 
def lstu(ag, dg): 
    lst = [] 
    # data list of first collection 
    dlofc = [] 
    # data list of second collection 
    dlosc = [] 

    # for every data unit that exists in data collection 
    for unit in ag.ld: 
     # lst.append([unit, globals()[unit].s+10]) 
     lst.append([unit, globals()[unit].s]) 
     dlofc.append([unit, globals()[unit].s]) 

    for unit in dg.ld: 
     lst.append([unit, globals()[unit].s]) 
     dlosc.append([unit, globals()[unit].s]) 

    # lambda function is used here to sort list by data value ([1] is index of the item) 
    lst = sorted(lst, key=lambda x: x[1], reverse=True) 
    # current index 
    ci = 0 

    previous_data = ["last data unit will be stored here", 0] 
    # sorted list 
    slst = [] 

    for unit in lst: 
     try: 
      next_data = lst[ci+1] 
     except IndexError: 
      next_data = ["endoflist", 0] 
     if previous_data[0] == "last data unit will be stored here": 
      pass 
     elif previous_data[0][:6] == unit[0][:6]: 
      if unit[0][:6] not in dlofc[0][0]: 
       slst.append([unit[0], unit[1], ci]) 
      elif unit[0][:6] not in dlosc[0][0]: 
       slst.append([unit[0], unit[1], ci]) 
      else: 
       print "Error" 

     previous_data = unit 
     ci += 1 

    print "slist below" 
    print slst 

    return lst 
# \@= END ##################################################################### 


print p01g01.ld 
print p02g01.ld 


data_list = lstu(p01g01, p02g01) 
print data_list 

Was ist der schnelle und korrekte Weg, um diese Daten zu sortieren?

+1

Haben Sie die 'sortierte' Funktion oder die' list.sort' Methode in Betracht gezogen? – skyking

+0

im Beispiel oben können Sie sehen, dass ich bereits sortiert verwendet, aber es ist nicht genug, um alle Anforderungen der neuen Liste zu erfüllen – Hsin

+0

Wissen Sie,// ​​erkennen, dass Sie die Art und Weise 'sortierten' und' list.sort' steuern können das Element beim Sortieren zu vergleichen ? Sobald Sie das kontrollieren können, sehe ich nicht, warum Sie nicht in der Lage sein sollten, 'sorted' oder' list.sort' zu verwenden. – skyking

Antwort

0

Gefundene Lösung. New lstu Funktion:

# replaced lambda with normal function 
def get_key(item): 
    return item[1] 


def lstu(ag, dg): 
    # ag list 
    agslst = [] 
    # dg list 
    dgslst = [] 

    # for every unit in first data collection 
    for unit in ag.u: 
     agslst.append([unit, globals()[unit].s]) 
    # sorted first data collection list 
    agslst = sorted(agslst, key=get_key, reverse=True) 
    print agslst 

    for unit in dg.u: 
     dgslst.append([unit, globals()[unit].s]) 
    # 2nd collection sorted list 
    dgslst = sorted(dgslst, key=get_key, reverse=True) 
    print dgslst 

    lst = [] 
    # last item 
    li = ["Empty", 0] 

    for item in range(0, len(agslst)+len(dgslst)+1): 
     if agslst and dgslst: 
      if agslst[0][1] == dgslst[0][1]: 
       if li[0][:6] == agslst[0][0][:6]: 
        li = dgslst.pop(0) 
        lst.append(li) 
       else: 
        li = agslst.pop(0) 
        lst.append(li) 

      elif agslst[0][1] > dgslst[0][1]: 
       li = agslst.pop(0) 
       lst.append(li) 
      else: 
       li = dgslst.pop(0) 
       lst.append(li) 

    return lst 

Auf diese Weise bereits erwähnten Anforderungen für neue erfüllen (und letzte) Liste

Ausgang:

[['p02g01r05', 5], ['p01g01r05', 4], ['p02g01r01', 4], ['p01g01r01', 3], ['p02g01r02', 2], ['p01g01r02', 2], ['p02g01r03', 2], ['p01g01r03', 2], ['p02g01r04', 2], ['p01g01r06', 2], ['p02g01r06', 1]], ['p01g01r04', 1]] 

Ich bin offen für alle Optimierungsvorschläge.

1

Haben Sie versucht, zuerst nach Zeichenfolgen zu sortieren und dann nach Nummern in Elementen zu sortieren?

>>> items = [['p02g01r05', 5], ['p02g01r01', 4], ['p01g01r05', 4], ['p01g01r01', 3], ['p01g01r02', 2], ['p01g01r03', 2], ['p01g01r06', 2], ['p02g01r02', 2], ['p02g01r03', 2], ['p02g01r04', 2], ['p01g01r04', 1], ['p02g01r06', 1]] 
>>> partially_sorted = sorted(items, key=lambda item: item[0], reverse=True) 
>>> sorted(partially_sorted, key=lambda item: item[1], reverse=True) 
[['p02g01r05', 5], ['p02g01r01', 4], ['p01g01r05', 4], ['p01g01r01', 3], ['p02g01r04', 2], ['p02g01r03', 2], ['p02g01r02', 2], ['p01g01r06', 2], ['p01g01r03', 2], ['p01g01r02', 2], ['p02g01r06', 1], ['p01g01r04', 1]] 
+0

Es wird nicht funktionieren. Es sollte einen Gegenstand von p01g01 und dann einen Gegenstand von p02g01 geben, wenn sie dasselbe "s" haben. Im obigen Beispiel erhalten wir viele Artikel mit demselben "s" aus derselben Sammlung. – Hsin

+0

Verschmelzt es grundsätzlich zwei sortierte Listen? Eine sortierte Liste namens p01g01 und andere, die p02g01 sind? – aisbaa

+0

Nein, python sort ist stabil https://en.wikipedia.org/wiki/Sorting_algorithm#Stability – aisbaa

Verwandte Themen