【问题标题】:Sorting List of Tuples with Multiconditions in PythonPython中具有多条件的元组排序列表
【发布时间】:2012-11-13 05:40:09
【问题描述】:

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

  1. 元组首先按照fwd_count的降序排列,
  2. 如果fwd_count中多个元组的count值相同,则只有count相同的元组需要根据rvs_count中的值降序排序。
  3. 顺序无关紧要,定位可以忽略,如果 a) 元组在fwd_countrvs_count 中具有相同的计数,或者 a) 元组在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_countrvs_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 为我的工作提供你们的 cmets

【问题讨论】:

  • 您能解释一下为什么您希望 ((6, 12), 1) 在结果中排​​在 ((5, 12), 1) 之前吗?
  • @wim 我错过了提及那些在“fwd_count”和“rvs_count”(如果存在)中具有相同计数的人,顺序无关紧要。由于 fwd_count 是按降序排序的,只要计数相同,python 列表就会根据“链接”id 对其进行降序排序,因为 ((6, 12), 1) > ((5, 12), 1),元组((6, 12), 1) 排在 ((5, 12), 1) 之前。但就我而言,这并不重要。希望我已经澄清了。感谢您的提问。
  • 我看不懂模式?为什么一切都在切换?
  • @enginefree 先生,我对你的理解并不相同。您是在问代码的目的吗?请澄清,我会尽力解释。
  • 你的问题很不清楚。为什么需要交换 (1, 36)(0, 36) 而不是 (6, 12)(5, 12) 对?

标签: python sorting


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我不确定您的排序标准的定义,但这是一种根据fwd_countrvs_count 中的值对pair 列表进行排序的方法。希望您可以使用它来获得您想要的结果。

    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 内置的元组排序机制对多个键进行排序,并反转元组中的一个值,使其成为逆序排序。

    【讨论】:

    • 仍然没有解决我的问题。
    猜你喜欢
    • 2013-11-07
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    相关资源
    最近更新 更多