2011-11-28 133 views
7

我是一個Python新手,試圖解析一個文件來創建一個內存分配表。我的輸入文件格式如下:變量作爲鍵的Python字典

48 bytes allocated at 0x8bb970a0 
24 bytes allocated at 0x8bb950c0 
48 bytes allocated at 0x958bd0e0 
48 bytes allocated at 0x8bb9b060 
96 bytes allocated at 0x8bb9afe0 
24 bytes allocated at 0x8bb9af60  

我的第一個目標是創建一個表來計算特定數量的字節分配的實例。換句話說,我所希望的上述輸入輸出會是這樣的:

48 bytes -> 3 times 
96 bytes -> 1 times 
24 bytes -> 2 times 

(現在,我不關心的內存地址)

由於我使用Python,我想使用字典做這件事將是正確的方式(基於大約3小時的閱讀Python教程)。這是一個好主意嗎?

在試圖使用字典來做到這一點時,我決定將字節數作爲'鍵',並將計數器作爲'值'。我的計劃是每發生一次密鑰都要增加計數器。截至目前,我的代碼片段如下:

# Create an empty dictionary 
allocationList = {} 

# Open file for reading 
with open("allocFile.txt") as fp: 
    for line in fp: 
     # Split the line into a list (using space as delimiter) 
     lineList = line.split(" ") 

     # Extract the number of bytes 
     numBytes = lineList[0]; 

     # Store in a dictionary 
     if allocationList.has_key('numBytes') 
      currentCount = allocationList['numBytes'] 
      currentCount += 1 
      allocationList['numBytes'] = currentCount 
     else 
      allocationList['numBytes'] = 1 

for bytes, count in allocationList.iteritems() 
    print bytes, "bytes -> ", count, " times" 

有了這個,我在「對象的has_key」出現語法錯誤調用,這使我懷疑它是否是可以使用變量作爲字典鍵。迄今爲止我所見過的所有例子都假設密鑰可用。在我的情況下,我只能在解析輸入文件時才能得到我的密鑰。

(請注意,我輸入文件可以運行到千行,用數百種不同的鍵)

感謝您的幫助,您可以提供。

+0

,我看到你報「的numBytes」,所以,你總是指不斷 – dmitry

+0

和你行後'如果allocationList.has_key(「的numBytes」)'和'else'省略冒號 - 它應該是語法錯誤 – dmitry

回答

10

學習語言與關於標準庫的語法和基本類型一樣多。 Python已經有一個讓你的任務變得非常簡單的類:collections.Counter

from collections import Counter 

with open("allocFile.txt") as fp: 
    counter = Counter(line.split()[0] for line in fp) 

for bytes, count in counter.most_common(): 
    print bytes, "bytes -> ", count, " times" 
+0

我覺得你的回答比任何其他人都更真實 –

+2

+1:如果你只對計數感興趣,那麼'計數器'就是要走的路。另一方面,OP寫道:*現在,我不關心內存地址* ---我想他可能遲早會需要一個超出Counter的定製解決方案。 –

+0

非常感謝您的解決方案。我試過了,但沒有奏效。這是因爲Counter只適用於Python> 2.7,我使用的是2.6.4。但它導致我:http://stackoverflow.com/questions/3594514/how-to-find-most-common-elements-of-a-list,在這裏我找到了一種方法來解決我的問題。但我將這個答案標記爲解決方案,因爲這可能是解決問題的最佳方法。 – Gautam

4

dictionnary的dict.has_key()方法disappeared in python3,來取代它,使用的關鍵字:

if numBytes in allocationList: # do not use numBytes as a string, use the variable directly 
    #do the stuff 

但在你的情況,你也可以更換所有的

if allocationList.has_key('numBytes') 
      currentCount = allocationList['numBytes'] 
      currentCount += 1 
      allocationList['numBytes'] = currentCount 
     else 
      allocationList['numBytes'] = 1 

與一行get

allocationList[numBytes] = allocationList.get(numBytes, 0) + 1 
+2

沒有必要使用'setdefault'設置兩次值;改用'dict.get'。 –

+0

@FerdinandBeyer:你說的對,使用setdefault有點矯枉過正,毫無用處。 –

+0

刪除'has_key'並使用'in'。謝謝你的提示。我可能正在閱讀一些過時的教程。 – Gautam

1

你絕對可以使用變量作爲代碼鍵。但是,您有一個名爲numBytes的變量,但正在使用包含文本"numBytes"的字符串 - 您正在使用字符串常量,而不是變量。這不會導致錯誤,但是是一個問題。請嘗試:

if numBytes in allocationList: 
    # do stuff 

此外,請考慮Counter。這是處理您正在查看的案例的便利課程。

4

你得到一個語法錯誤,因爲你在這行的末尾缺少冒號:

if allocationList.has_key('numBytes') 
            ^

你的做法是好的,但它可能是更容易使用dict.get()有默認值:

allocationList[numBytes] = allocationList.get(numBytes, 0) + 1 

由於您的allocationList是字典而不是列表,因此您可能希望爲該變量選擇一個不同的名稱。

+0

謝謝。我對「:」沒有任何線索。剛剛發現我在'for'語句結尾處還需要一個。 – Gautam