2012-11-11 150 views
0

我在使用Python 2.6.2。我有一個元組列表pair,我喜歡使用兩個嵌套條件進行排序。在Python中對多元化的元組進行排序列表

  1. 的元組的降序fwd_count計數順序第一排序,
  2. 如果計數的值是用於fwd_count多於一個元組是相同的,只需要那些具有相等計數的元組以降序進行排序基於rvs_count中的值。
  3. 的順序並不重要,定位可以忽略不計,如果 一)元組在fwd_count相同的計數,並在rvs_count,或 一)元組具有相同的計數fwd_countrvs_count
  4. 不存在

我設法寫下面的代碼:

pair=[((0, 12), (0, 36)), ((1, 12), (0, 36)), ((2, 12), (1, 36)), ((3, 12), (1, 36)), ((1, 36), (4, 12)), ((0, 36), (5, 12)), ((1, 36), (6, 12))] 

fwd_count = {} 
rvs_count = {} 

for link in sorted(pair): 
    fwd_count[link[0]] = 0 
    rvs_count[link[1]] = 0 

for link in sorted(pair): 
    fwd_count[link[0]] += 1 
    rvs_count[link[1]] += 1 

#fwd_count {(6, 12): 1, (5, 12): 1, (4, 12): 1, (1, 36): 2, (0, 36): 2} 
#rvs_count {(3, 12): 1, (1, 12): 1, (1, 36): 2, (0, 12): 1, (2, 12): 1, (0, 36): 1} 

fwd_count_sort=sorted(fwd_count.items(), key=lambda x: x[1], reverse=True) 
rvs_count_sort=sorted(rvs_count.items(), key=lambda x: x[1]) 

#fwd_count_sort [((1, 36), 2), ((0, 36), 2), ((6, 12), 1), ((5, 12), 1), ((4, 12), 1)] 
#rvs_count_sort [((3, 12), 1), ((1, 12), 1), ((1, 36), 2), ((0, 12), 1), ((2, 12), 1), ((0, 36), 1)] 

我找的結果是:

#fwd_count_sort_final [((0, 36), 2), ((1, 36), 2), ((6, 12), 1), ((5, 12), 1), ((4, 12), 1)] 

其中(1, 36)(0, 36)的位置與fwd_count_sort中的位置交換位置。

問:

  1. 有沒有更好的方式做多的條件使用fwd_count,並在同一時間rvs_count信息分類? (只有元組很重要,不需要記錄排序值),或
  2. 我需要爲每個條件單獨對它進行排序(正如我上面所做的那樣),並嘗試找到將其整合以獲得結果的意思I通緝?

我目前正在研究上述項目2,但試圖瞭解是否有任何更簡單的方法。

這是我能找到的最接近我在http://stygianvision.net/updates/python-sort-list-object-dictionary-multiple-key/「雙向排序與數值」的內容,但不確定如果我使用{tuple:{fwd_count:rvs_count}}關係創建一個新詞典。

更新:2012年11月12日 - 解決

我設法用列表來解決這個問題。以下是代碼,希望對於那些正在對多條件列表進行排序的人員有用。

#pair=[((0, 12), (0, 36)), ((1, 12), (1, 36)), ((2, 12), (0, 36)), ((3, 12), (1, 36)), ((1, 36), (4, 12)), ((0, 36), (5, 12)), ((1, 36), (6, 12))] 

rvs_count = {} 
fwd_count = {} 

for link in sorted(pair): 
    rvs_count[link[0]] = 0 
    fwd_count[link[1]] = 0 

for link in sorted(pair): 
    rvs_count[link[0]] += 1 
    fwd_count[link[1]] += 1 

keys = [] 
for link in pair: 
    if link[0] not in keys: 
     keys.append(link[0]) 
    if link[1] not in keys: 
     keys.append(link[1]) 

aggregated = [] 
for k in keys: 
    a = -1 
    d = -1 
    if k in fwd_count.keys(): 
     a = fwd_count[k] 
    if k in rvs_count.keys(): 
     d = rvs_count[k] 
    aggregated.append(tuple((k, tuple((a,d))))) 

def compare(x,y): 
    a1 = x[1][0] 
    d1 = x[1][1] 
    a2 = y[1][0] 
    d2 = y[1][1] 
    if a1 > a2: 
     return - a1 + a2 
    elif a1 == a2: 
     if d1 > d2: 
      return d1 - d2 
     elif d1 == d2: 
      return 0 
     else: 
      return d1 - d2 
    else: 
     return - a1 + a2 

s = sorted(aggregated, cmp=compare) 
print(s) 

j = [v[0] for v in s] 
print(j) 

感謝安德烈·費爾南德斯,布賴恩和杜克大學對我的工作給你的意見

+0

你能解釋一下你爲什麼要((6,12),1)排序之前((5,12),1)在結果? – wim

+0

@wim我錯過了提及那些在「fwd_count」和「rvs_count」(如果存在)中具有相同計數的人的順序無關緊要。由於fwd_count是按降序排序的,因此每當count是相同的時候,python list會根據「link」id對它進行降序排序,因爲((6,12),1)>((5,12),1) ((6,12),1)在((5,12),1)之前排序。但對我而言並不重要。希望我澄清得很好。感謝您的詢問。 –

+1

我不明白這個模式?爲什麼一切都被切換? – enginefree

回答

1

如果您需要交換所有第一個(對)元素(而不僅僅是(1, 36)(0, 36)),你可以做 fwd_count_sort=sorted(rvs_count.items(), key=lambda x: (x[0][1],-x[0][0]), reverse=True)

0

我不是你的排序標準的定義完全相信,但是這是一個方法來排序pair列表根據fwd_countrvs_count中的值。希望你可以用它來達到你想要的結果。

def keyFromPair(pair): 
    """Return a tuple (f, r) to be used for sorting the pairs by frequency.""" 
    global fwd_count 
    global rvs_count 

    first, second = pair 
    countFirstInv = -fwd_count[first] # use the negative to reverse the sort order 
    countSecond = rvs_count[second] 

    return (first, second) 

pairs_sorted = sorted(pair, key = keyFromPair) 

的基本思想是使用Python的內置元組排序機制進行排序多個鍵,並且反轉值中的一個元組,從而使其成爲反向排序。

+0

仍然不能解決我的問題。 – Duke

相關問題