簡體   English   中英

如何 append 只有唯一值到字典中的鍵?

[英]How to append only unique values to a key in a dictionary?

抱歉,這可能是一個完整的菜鳥問題,盡管我是 python 的新手,無法實施任何在線建議,使它們真正起作用。 我需要減少較大文件的代碼運行時間,因此需要減少我正在執行的迭代次數。

我如何將下面的 append_value function 修改為 append 只有 UNIQUE 值到 dict_obj,並消除對另一系列迭代的需要,以便稍后執行此操作。

編輯:抱歉,這是一個示例輸入/輸出

示例輸入:

6
5 6
0 1
1 4
5 4
1 2
4 0

樣本 Output:

1
4

我正在嘗試解決: http://orac.amt.edu.au/cgi-bin/train/problem.pl?problemid=416

Output 結果

input_file = open("listin.txt", "r")
output_file = open("listout.txt", "w")

ls = []
n = int(input_file.readline())
for i in range(n): 
    a, b = input_file.readline().split()
    ls.append(int(a))
    ls.append(int(b))

def append_value(dict_obj, key, value):          # How to append only UNIQUE values to
    if key in dict_obj:                          # dict_obj?
        if not isinstance(dict_obj[key], list):
            dict_obj[key] = [dict_obj[key]]
        dict_obj[key].append(value)
    else:
        dict_obj[key] = value

mx = []
ls.sort()
Dict = {}
for i in range(len(ls)):
    c = ls.count(ls[i])
    append_value(Dict, int(c), ls[i])
    mx.append(c)

x = max(mx)
lss = []

list_set = set(Dict[x])                     #To remove the need for this
unique_list = (list(list_set))
for x in unique_list:
    lss.append(x)

lsss = sorted(lss)
for i in lsss:
    output_file.write(str(i) + "\n")
    
output_file.close()
input_file.close()

謝謝

您的問題“如何將 append 個唯一值分配給此容器”的答案非常簡單:將其從list更改為set (如@ShadowRanger 在評論中建議的那樣)。 不過,這實際上不是關於字典的問題。 您不是將值附加到“dict_obj”,而是附加到存儲在字典中的列表。

由於您鏈接到的來源顯示這是一個針對編碼新手的培訓問題,您應該知道將列表更改為集合可能是個好主意,但這不是性能問題的原因。

問題歸結為:給定一個包含整數列表的文件,打印最常見的整數。 您當前的代碼遍歷列表,對於每個索引i ,遍歷整個列表以計算與ls[i]的匹配項(這是行c = ls.count(ls[i]) )。

有些操作比其他操作更昂貴:調用count()是 Python 列表中更昂貴的操作之一。 每次調用時它都會讀取整個列表。 這是一個O(n) function,它在一個長度為n的循環內,花費O(n^2)時間。 對非唯一元素的所有set()過濾總共需要O(n)時間(在實踐中甚至相當快)。 像這樣識別隱藏在循環中的線性時間函數是優化中的一個常見主題,但是分析您的代碼會識別出這一點。

通常,您會希望使用 Python 標准庫中的Counter class 之類的東西來進行頻率計數。 不過,這種做法違背了這個訓練問題的全部要點,即鼓勵您改進用於查找列表中最頻繁出現的元素的蠻力算法。 解決這個問題的一種可能方法是閱讀Counter的描述,並嘗試使用普通的 Python 字典自己模仿它的行為。

回答你沒有問過的問題:你的整個方法是矯枉過正。

  1. 您無需擔心唯一性; 問題提示保證如果你看到2 5 ,你永遠不會看到5 2 ,也不會重復2 5
  2. 你甚至不關心誰和誰是朋友,你只關心一個人有多少朋友

所以甚至不用費心去配對。 只需計算每個玩家 ID 出現次數即可。 如果你看到2 5 ,那就意味着2多了一個朋友,而5多了一個朋友,不管他們誰是朋友。

整個問題可以簡化為一個簡單的練習,即分離玩家 ID 並將它們全部計數(因為每次出現都意味着多了一個獨特的朋友),然后只保留計數最高的那些。

一個相當慣用的解決方案(從 stdin 讀取並寫入 stdout;調整它以打開文件留作練習)類似於:

import sys

from collections import Counter
from itertools import chain, islice

def main():
    numlines = int(next(sys.stdin))
    friend_pairs = map(str.split, islice(sys.stdin, numlines)) # Convert lines to friendship pairs
    counts = Counter(chain.from_iterable(friend_pairs))        # Flatten to friend mentions and count mentions to get friend count
    max_count = max(counts.values())                           # Identify maximum friend count
    winners = [pid for pid, cnt in counts.items() if cnt == max_count]
    winners.sort(key=int)                                      # Sort winners numerically
    print(*winners, sep="\n")

if __name__ == '__main__':
    main()

在線試用!

從技術上講,它甚至不需要使用islice也不需要存儲到numlines (開頭的行數可能對低級語言有用,可以為結果預分配數組,但是對於 Python,您可以逐行讀取直到您用完了),所以main的前兩行可以簡化為:

next(sys.stdin)
friend_pairs = map(str.split, sys.stdin)

但無論哪種方式,您都不需要統一友誼,也不需要保留任何關於誰和誰是朋友的知識來弄清楚誰擁有最多的朋友,所以省去一些麻煩並跳過不必要的工作。

如果您打算在字典的每個值中都有一個列表,為什么不按照您在每個鍵上迭代的方式進行迭代。

if key in dict_obj.keys():
    for elem in dict_obje[key]:  # dict_obje[key] asusming the value is a list
        if (elem == value):
        else:
    # append the value to the desired list
else:
    dic_obj[key] = value

暫無
暫無

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

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