62
Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.
Learn more.
Làm cách nào để chia chuỗi byte thành một danh sách các dòng?
Trong Python 2 tôi đã có:
rest = "some\nlines"
for line in rest.split["\n"]:
print line
Mã trên được đơn giản hóa vì lợi ích của sự ngắn gọn, nhưng bây giờ sau khi xử lý regex, tôi có một mảng byte trong rest
và tôi cần lặp lại các dòng.
Hỏi ngày 13 tháng 12 năm 2012 lúc 10:28Dec 13, 2012 at 10:28
2
Không có lý do để chuyển đổi thành chuỗi. Chỉ cần cung cấp cho các tham số byte split
. Chia chuỗi với chuỗi, byte với byte.
>>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
Đã trả lời ngày 26 tháng 2 năm 2013 lúc 17:33Feb 26, 2013 at 17:33
Janus troelsenjanus troelsenJanus Troelsen
Huy hiệu vàng 19.6K1414 gold badges128 silver badges191 bronze badges
2
Giải mã các byte thành Unicode [STR] và sau đó sử dụng str.split
:
Python 3.2.3 [default, Oct 19 2012, 19:53:16]
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = b'asdf\nasdf'
>>> a.split['\n']
Traceback [most recent call last]:
File "", line 1, in
TypeError: Type str doesn't support the buffer API
>>> a = a.decode[]
>>> a.split['\n']
['asdf', 'asdf']
>>>
Bạn cũng có thể chia bằng
>>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
0, nhưng tôi đoán bạn phải làm việc với các chuỗi không phải là byte. Vì vậy, hãy chuyển đổi tất cả dữ liệu đầu vào của bạn thành >>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
1 càng sớm càng tốt và chỉ hoạt động với Unicode trong mã của bạn và chuyển đổi nó thành byte khi cần thiết cho đầu ra càng muộn càng tốt.Đã trả lời ngày 13 tháng 12 năm 2012 lúc 10:40Dec 13, 2012 at 10:40
Warvariucwarvariucwarvariuc
54,9K36 Huy hiệu vàng167 Huy hiệu bạc226 Huy hiệu Đồng36 gold badges167 silver badges226 bronze badges
0
thử cái này.. .
>>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
2 >>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
3>>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
3Sau đó, bạn có thể làm
>>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
4Đã trả lời ngày 13 tháng 12 năm 2012 lúc 10:49Dec 13, 2012 at 10:49
Namitnamitnamit
6.4804 Huy hiệu vàng33 Huy hiệu bạc40 Huy hiệu đồng4 gold badges33 silver badges40 bronze badges
Tôi có dữ liệu đến từ một bộ mã hóa quay tuyệt đối. Nó rộng 24 bit. 12 bit là số lần lượt và 12 bit là góc.
Tôi đang đọc dữ liệu với Arduino và gửi nó đến máy tính qua một cổng nối tiếp. Điều tự nhiên nhất để làm là kết hợp tất cả các bit và gửi nó dưới dạng 3 byte.
Chia 3 byte thành 12 bit/12 bit tại máy tính trong Python 3 cảm thấy không liên quan đến tôi. Đây là những gì tôi có cho đến nay:
import struct
# fake message, H is header last 3 bytes are data
msg = b'H\x90\xfc\xf9'
header, bytes3 = struct.unpack['>c3s', msg]
print['bytes3 ', bytes3]
val = int.from_bytes[bytes3, 'big']
print['val ', val]
print['bin[val] ', bin[val]]
upper12 = val >> 12
print['bin[upper12]', bin[upper12]]
lower12 = val & 0b000000000000111111111111
print['bin[lower12]', bin[lower12]]
cung cấp cho đầu ra bảng điều khiển của
bytes3 b'\x90\xfc\xf9'
val 9501945
bin[val] 0b100100001111110011111001
bin[upper12] 0b100100001111
bin[lower12] 0b110011111001
Mã này có vẻ hoạt động tốt, nhưng bitshifting [
>>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
5] và bitwise anding [>>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
6] là một chút wonky. Ngoài ra, thật buồn cười khi chỉ định Big Endian hai lần: đầu tiên trong chuỗi định dạng >>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
7 và thứ hai trong >>> a = b'asdf\nasdf'
>>> a.split[b'\n']
[b'asdf', b'asdf']
8.Có một cách thanh lịch hơn để đạt được điều này?
Cập nhật: Thời gian
Tôi vẫn đang ở trên hàng rào mà kỹ thuật nào là Pythonic nhất. Nhưng tôi đã thực hiện các kỹ thuật thời gian 3:
- Kỹ thuật gốc ở trên
- Kỹ thuật của Alexv với các số nguyên 16 bit không dấu chồng lên nhau
- Thay đổi giao thức comms để gửi số nguyên không dấu 4 byte mà
9 có thể chuyển đổi trực tiếp sang số nguyên>>> a = b'asdf\nasdf' >>> a.split[b'\n'] [b'asdf', b'asdf']
import struct
import time
import random
import timeit
def gen_random_msg[nbyte = 3]:
# make a n byte message with header 'H' prepended
data = random.randint[0, 2**12-1]
data = data.to_bytes[nbyte, 'big']
msg = b'H' + data
return msg
def original_recipe[]:
msg = gen_random_msg[3]
header, bytes3 = struct.unpack['>c3s', msg]
val = int.from_bytes[bytes3, 'big']
upper12 = val >> 12
lower12 = val & 4095 # 4095 = 2**12-1
def overlap16bits[]:
msg = gen_random_msg[3]
header, val = struct.unpack['>cH', msg[0:-1]]
upper12 = val >> 4
lower12 = struct.unpack['>H', msg[2:]][0] & 0xfff
def fourbyte[]:
msg = gen_random_msg[4]
header, val = struct.unpack['>cI', msg]
upper12 = val >> 12
lower12 = val & 4095 # 4095 = 2**12-1
niter = int[1e6]
t0 = time.time[]
for i in range[niter]: gen_random_msg[3]
t1 = time.time[]
for i in range[niter]: gen_random_msg[4]
t2 = time.time[]
for i in range[niter]: original_recipe[]
t3 = time.time[]
for i in range[niter]: overlap16bits[]
t4 = time.time[]
for i in range[niter]: fourbyte[]
t5 = time.time[]
gentime3 = t1-t0
gentime4 = t2-t1
original_time = t3-t2
overlap_time = t4-t3
fourbyte_time = t5-t4
print['gentime3: ', gentime3, '. gentime4: ', gentime4]
print ['original recipe: ', original_time - gentime3]
print ['overlap 16 bits: ', overlap_time - gentime3]
print ['four bytes: ', fourbyte_time - gentime4]
Điều này có đầu ra bảng điều khiển:
gentime3: 3.478888988494873 . gentime4: 3.4476888179779053
original recipe: 1.3416340351104736
overlap 16 bits: 1.435237169265747
four bytes: 0.7956202030181885
Phải mất nhiều thời gian hơn để tạo tin nhắn giả 1m hơn là xử lý các byte. Kỹ thuật nhanh nhất là thay đổi thông số kỹ thuật comms và đệm 3 byte để tạo số nguyên không dấu 4 byte. Tốc độ tăng là tốt [xấp xỉ 2 lần] cho "Fourbyte", nhưng yêu cầu thay đổi đặc tả thông tin liên lạc. Tại thời điểm này, tôi nghĩ rằng nó đi theo sở thích cá nhân về thuật toán nào là tốt nhất.