2008-12-22 22 views
6

Tôi đang cố gắng nói chuyện với một thiết bị sử dụng python. Tôi đã được trao một bộ byte chứa thông tin lưu trữ. Làm thế nào tôi có thể chuyển đổi dữ liệu vào các giá trị chính xác:Làm cách nào để chuyển đổi một phần của một bộ mã vạch python (mảng byte) thành một số nguyên

phản ứng = (0, 0, 117, 143, 6)

4 giá trị đầu tiên là một int 32-bit nói với tôi bao nhiêu byte đã được sử dụng và giá trị cuối cùng là phần trăm được sử dụng.

Tôi có thể truy cập tuple dưới dạng phản hồi [0] nhưng không thể xem cách tôi có thể nhận được 4 giá trị đầu tiên vào int mà tôi yêu cầu.

Trả lời

11

Xem Convert Bytes to Floating Point Numbers in Python

Bạn có thể muốn sử dụng các mô-đun cấu trúc, ví dụ

import struct 

response = (0, 0, 117, 143, 6) 
struct.unpack(">I", ''.join([chr(x) for x in response[:-1]])) 

Giả sử int chưa ký. Có thể có một cách tốt hơn để thực hiện chuyển đổi để giải nén, việc hiểu danh sách với tham gia chỉ là điều đầu tiên mà tôi nghĩ ra.

EDIT: Xem thêm nhận xét của on về câu trả lời này liên quan đến tính cuối cùng.

EDIT # 2: Nếu bạn không ngại sử dụng mô-đun mảng, đây là phương pháp thay thế làm giảm nhu cầu đọc danh sách. Nhờ @JimB để chỉ ra rằng việc giải nén cũng có thể hoạt động trên các mảng.

import struct 
from array import array 

response = (0, 0, 117, 143, 6) 
bytes = array('B', response[:-1]) 
struct.unpack('>I', bytes) 
+1

Tôi khuyên rằng định dạng gói là "> I" tức là lớn endian; 0x0000758f (30095₁₀) cho số byte ngẫu nhiên có vẻ nhiều hơn 0x8f750000 (2406809600₁₀) – tzot

13

Would,

num = (phản ứng [0] < < 24) + (phản ứng [1] < < 16) + (phản ứng [2] < < 8) + phản ứng [3]

đáp ứng nhu cầu của bạn?

viện trợ

+2

khi đọc câu trả lời ở trên bằng cách nhập mô-đun, sử dụng vòng lặp và hiểu cho một điều nhỏ nhặt như thế này, tôi thực sự bắt đầu gãi đầu ... câu trả lời này thực sự là như thế nào (và nên được) thực hiện ở bất cứ nơi nào, và không có gì sẽ đánh bại điều này về mặt tốc độ và sự đơn giản ... – Tom

+0

Một cách dễ dàng để làm điều đó – user2578666

4

OK, Bạn không chỉ định endinanness hay số nguyên được ký kết hoặc và nó (có lẽ) là nhanh hơn để với các module struct nhưng:

b = (8, 1, 0, 0) 
sum(b[i] << (i * 8) for i in range(4)) 
+0

chỉ để tham khảo này là dành cho người nhỏ tuổi và có thể có thể được cải thiện một chút là 'tổng (b [i] << (i * 8) cho i trong phạm vi (len (b)))' để cho phép đầu vào kích thước biến hoặc 'tổng (phản hồi [i] << (i * 8) cho i trong phạm vi (len (phản hồi) -1)) 'cho OP. – Caltor

+0

@Ad__ Tôi thích giải pháp này vì nó có lẽ nhanh hơn struct.unpack và không giống như phương thức đó, nó không yêu cầu nhập mô-đun. Bạn có thể cung cấp một phiên bản mà có thể xử lý lớn-endian mặc dù xin vui lòng? – Caltor

4

Bạn cũng có thể làm việc sử dụng các mô-đun mảng

import struct 
from array import array 
response = (0, 0, 117, 143, 6) 
a = array('B', response[:4]) 
struct.unpack('>I', a) 

(30095L,) 
+0

Tôi đã thử cách tiếp cận này quá, nhưng quyết định đi với một danh sách hiểu và tham gia() thay vào đó, để tránh nhập khẩu mô-đun khác, và vì không phải là đặc biệt rõ ràng, không may. – Jay

+0

Tôi quên rằng cấu trúc có thể gói mảng [câu trả lời cố định], mà tôi nghĩ rằng làm cho phiên bản này tốt hơn một chút so với danh sách comp. – JimB

+0

Tốt, tôi không biết nó có thể làm điều đó, bỏ qua điều đó trong tài liệu. Tôi cũng sẽ thêm nó vào câu trả lời của tôi cũng như một câu trả lời thay thế. – Jay

0

Làm thế nào về việc sử dụng các chức năng bản đồ:

a = (0, 0, 117, 143, 6) 
b = [] 
map(b.append, a) 

Ngoài ra, tôi không biết nếu điều này là bạn đang tìm kiếm:

response = (0, 0, 117, 143, 6) 
response[0:4] 
3

này trông giống như một công việc cho giảm!

Những gì bạn về cơ bản cần là, bit-shift một byte tại một thời điểm, và sau đó thêm (bổ sung) byte tiếp theo trong chuỗi.

a = (0, 0, 117, 143, 6) 
reduce(lambda x, y: (x<<8) + y, a) 
7704326 
+0

-1 Đọc câu hỏi. Có FIVE byte. OP cho biết 4 đầu tiên là int 32 bit. Cuối cùng là tỷ lệ phần trăm (6%). –

+0

@ John: Tôi nghĩ rằng đó chỉ là một sai lầm nhỏ, chỉ cần thay đổi dòng thứ hai '' a'' thành '' a [: 4] '' và mã hoạt động khi cần thiết bởi OP (ít nhất là nếu người dùng cuối lớn dự định). Không cần phải downvote trực tiếp. –

+0

@Kristian bất kỳ cơ hội nào của phiên bản này dành cho người cuối cùng ít được không? – Caltor