簡體   English   中英

Python - 遍歷字典以在第一個 position 中找到最頻繁出現的值

[英]Python - Looping through a dictionary to find most frequent value in first position

我正在處理一個程序的一部分,從字典中返回某些值,場景如下:

“投票規則按輪次進行。在每一輪中,在代理排名的前 position 中出現最少的備選方案被刪除,然后重復該過程。當最后一組備選方案被刪除時(一個或可能多個) ,那么這最后一組就是可能獲勝者的集合。” 我正在嘗試歸還這最后一組。

Alternatives = 字典中的值,它們采用列表格式。 代理 = 字典中的鍵。 該詞典是一個“偏好配置文件”,將每個備選方案列為偏好,1 = 最優選。 示例字典:智能體 1 最喜歡備選方案 3

preferences = {
 1: [4, 2, 1, 3],
 2: [4, 3, 1, 2],
 3: [2, 3, 1, 2],
 4: [1, 3, 4, 2],
 5: [2, 3, 4, 1],
 6: [2, 1, 3, 4]}

我嘗試對此進行編碼:

def votingRule(preferences):
    dictionary = preferences.copy()
    removed_values = set()
    while dictionary:
        values = set()
        for vals in dictionary.values():
            values.update(vals) 
        
        frequencies = {value: 0 for value in values}
        for values in dictionary.values():
            try:
                if values[0] in frequencies:
                    frequencies[values[0]] += 1 
            except IndexError:
                pass
        print("1st Freqs",frequencies) # this stage returns a correct count of each element

        if not frequencies:
            return set()
        min_frequency = min(frequencies.values())
           
        current_removed_values = set()
        for value in frequencies:
            for ele in dictionary:
                if frequencies[value] == min_frequency:
                    for key in dictionary:
                        if value in dictionary[key]:
                            dictionary[key].remove(value)
                            current_removed_values.add(value)
                break
            else:
                dictionary = {}                            
        removed_values = current_removed_values      
    return removed_values

我可以在每一輪中返回每個元素的正確頻率計數,但我無法正確識別最終的一組刪除值。

例如,使用上面的示例我的代碼將返回:

Step by step output = 
1st Freqs {1: 1, 2: 3, 3: 0, 4: 2}
[4, 2, 1, 3]
1st Freqs {1: 1, 2: 3, 4: 2}
[4, 2, 1]
1st Freqs {2: 3, 4: 3}
[4, 2] #this would be the correct set to return as they have the same frequency but the loop continues
1st Freqs {2: 1}
[2]

Final output = {2}
Desired final output = {4, 2}

誰能建議如何糾正這個問題? 有沒有更有效的方法來解決這個問題?

謝謝

首選項數組的含義

preferences = {
 1: [4, 2, 1, 3],
 2: [4, 3, 1, 2],
 3: [2, 3, 1, 2],
 4: [1, 3, 4, 2],
 5: [2, 3, 4, 1],
 6: [2, 1, 3, 4]}

偏好字典代表:

  • 6名投票人(代理人)
  • 智能體 1 在第一輪更喜歡 4,在第二輪更喜歡 2,在第三輪更喜歡 1,在第四輪更喜歡 3
  • 代理人 2 在第一輪中首選 4,在第二輪中首選 3,在第三輪中首選 1,在第四輪中首選 2,
  • 等等

投票規則

投票規則輪流生效(帖子略有修改)

  • 在每一輪中,刪除當前代理排名索引中出現頻率最低(最不常見)的備選方案(僅當只有一個時)
  • 索引遞增,並使用下一個索引重復該過程。
  • 當只有一個候選人或我們遍歷所有回合時,該過程終止

代碼

def votingRule(preferences):
    
    len_vals = len(list(preferences.values())[0])           # number of values in each list
    candidates = set(range(1, len_vals+1))                  # condidates is 1 to number of values in lists

    for index in range(len_vals):
        # Get most common value for current index
        vals = [v[index] for v in preferences.values()]    # values for current index
        cnts = Counter(vals)                               # Count of values at current index
        _, freq = cnts.most_common()[:-2:-1][0]            # frequency of least common

        # candidates which are the least common
        least_common_candidates = set(tup[0] for tup in cnts.items() if cnts[tup[0]] == freq)

        # Remove if only one least common
        if len(least_common_candidates) == 1:
            candidates = candidates - least_common_candidates

        # Done if only one candidate left
        if len(candidates) == 1:
            break
            
    return candidates

測試

 print(votingRule(preferences))
 # Output: {2, 4}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM