2011-11-28 34 views
7

Tôi là một người mới sử dụng Python đang cố phân tích một tệp để tạo bảng phân bổ bộ nhớ. Tệp nhập của tôi có định dạng sau:Từ điển Python với các biến là các phím

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  

Mục tiêu đầu tiên của tôi là tạo bảng tính số lần phân bổ byte cụ thể. Nói cách khác, đầu ra mong muốn của tôi cho đầu vào ở trên sẽ là một cái gì đó như:

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

(cho bây giờ, tôi không phải lo lắng về các địa chỉ bộ nhớ)

Kể từ khi tôi đang sử dụng Python, tôi nghĩ làm điều này bằng cách sử dụng một từ điển sẽ là đúng cách để đi (dựa trên khoảng 3 giờ 'giá trị đọc hướng dẫn Python). Đó có phải là một ý tưởng tốt?

Khi cố gắng thực hiện điều này bằng từ điển, tôi quyết định đặt số byte thành 'khóa' và bộ đếm làm 'giá trị'. Kế hoạch của tôi là tăng bộ đếm trên mọi lần xuất hiện của khóa. Tính đến bây giờ, đoạn mã của tôi là như sau:

# 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" 

Với điều này, tôi nhận được một lỗi cú pháp trong 'has_key' gọi, dẫn tôi đặt câu hỏi liệu nó thậm chí có thể sử dụng các biến như là chìa khóa từ điển. Tất cả các ví dụ tôi đã thấy cho đến nay giả định rằng các phím có sẵn trả trước. Trong trường hợp của tôi, tôi chỉ có thể lấy khóa khi tôi phân tích tệp đầu vào.

(Lưu ý rằng tập tin đầu vào của tôi có thể chạy vào hàng ngàn dòng, với hàng trăm các phím khác nhau)

Cảm ơn bạn cho bất kỳ giúp bạn có thể cung cấp.

+0

như tôi thấy bạn trích dẫn 'numBytes', vì vậy, bạn luôn được đề cập đến liên tục – dmitry

+0

và bạn bỏ qua ruột kết ở dòng sau 'nếu allocationList.has_key ('numBytes')' và 'else' - nó phải được lỗi cú pháp – dmitry

Trả lời

10

Tìm hiểu ngôn ngữ cũng giống như về cú pháp và các loại cơ bản như về thư viện chuẩn. Python đã có một lớp làm nhiệm vụ của bạn rất dễ dàng: 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

Tôi cảm thấy câu trả lời của bạn là đúng hơn bất cứ ai elses ở đây –

+2

+1: Nếu bạn chỉ quan tâm đến đếm, 'Counter' là con đường để đi. Mặt khác, OP đã viết: * bây giờ, tôi không quan tâm đến địa chỉ bộ nhớ * --- Tôi cho rằng anh ta có thể sớm hay muộn cần một giải pháp tùy chỉnh vượt ra ngoài 'Counter'. –

+0

Cảm ơn bạn rất nhiều vì giải pháp này. Tôi đã thử nó, nhưng nó không hoạt động. Điều này là do Bộ đếm chỉ khả dụng cho Python> 2.7 và tôi đang sử dụng 2.6.4. Nhưng nó đã dẫn tôi đến: http://stackoverflow.com/questions/3594514/how-to-find-most-common-elements-of-a-list, và ở đây tôi tìm thấy một cách để giải quyết vấn đề của tôi. Nhưng tôi đánh dấu câu trả lời này là giải pháp, bởi vì đây có lẽ là cách tốt nhất để giải quyết vấn đề. – Gautam

4

Phương pháp dict.has_key() của dictionnary có disappeared in python3, để thay thế nó, sử dụng trong từ khóa:

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

Nhưng trong trường hợp của bạn, bạn cũng có thể thay thế tất cả các

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

với một dòng với get:

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

Không cần thiết lập giá trị hai lần bằng 'setdefault'; sử dụng 'dict.get' để thay thế. –

+0

@ FerdinandBeyer: bạn nói đúng, hơi quá mức và vô ích khi sử dụng setdefault. –

+0

Đã xóa 'has_key' và sử dụng 'in'. Cảm ơn vì tiền hỗ trợ. Tôi có lẽ đã đọc một số hướng dẫn đã lỗi thời. – Gautam

1

Bạn chắc chắn nhất có thể sử dụng các biến như khóa dict. Tuy nhiên, bạn có một biến được gọi là numBytes, nhưng đang sử dụng một chuỗi chứa văn bản "numBytes" - bạn đang sử dụng hằng số chuỗi chứ không phải biến. Điều đó sẽ không gây ra lỗi, nhưng là một vấn đề. Thay vào đó, hãy thử:

if numBytes in allocationList: 
    # do stuff 

Ngoài ra, hãy xem xét Counter. Đây là một lớp tiện lợi để xử lý trường hợp bạn đang xem.

4

Bạn nhận được một lỗi cú pháp vì bạn đang thiếu ruột kết ở phần cuối của dòng này:

if allocationList.has_key('numBytes') 
            ^

cách tiếp cận của bạn là tốt, nhưng nó có thể được dễ dàng hơn để sử dụng dict.get() với một giá trị mặc định:

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

allocationList là từ điển và không phải là danh sách, bạn có thể muốn chọn tên khác cho biến.

+0

Cảm ơn. Tôi không có đầu mối về ":". Chỉ cần tìm ra rằng tôi cũng cần một ở phần cuối của câu lệnh 'for' của tôi. – Gautam

Các vấn đề liên quan