2011-11-28 87 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