0

我正在使用 Python 2.6.2。我有一个元组列表pair,我喜欢使用两个嵌套条件对其进行排序。

  1. 元组首先按 的降序排列fwd_count
  2. 如果 中的多个元组的 count 值相同fwd_count,则只有具有相同计数的元组需要根据 中的值按降序排序rvs_count
  3. 如果 a) 元组在 infwd_count和 in 中具有相同的计数rvs_count,或者 a) 元组在 in 和 中具有相同的计数fwd_count并且不存在于rvs_count

我设法编写了以下代码:

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. 我是否需要为每个条件单独排序(如我上面所做的那样)并尝试找到将其整合以获得我想要的结果的平均值?

我目前正在研究上面的第 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)

感谢 Andre Fernandes、Brian 和 Duke 对我的工作提出意见

4

2 回答 2

1

如果您需要交换所有第一个(一对)元素(而不仅仅是(1, 36)and (0, 36)),您可以这样做 fwd_count_sort=sorted(rvs_count.items(), key=lambda x: (x[0][1],-x[0][0]), reverse=True)

于 2012-11-12T00:49:23.670 回答
0

我不确定您的排序标准的定义,但这是一种根据andpair中的值对列表进行排序的方法。希望您可以使用它来获得您想要的结果。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 的内置元组排序机制对多个键进行排序,并将元组中的一个值反转,使其成为逆序排序。

于 2012-11-12T00:43:02.817 回答