Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah saya boleh menghuraikan baris fail lebar tetap dengan cekap dalam Python?

Bagaimanakah saya boleh menghuraikan baris fail lebar tetap dengan cekap dalam Python?

Barbara Streisand
Barbara Streisandasal
2024-10-30 17:09:26447semak imbas

How can I efficiently parse fixed-width file lines in Python?

Penghuraian Pantas Garisan Fail Lebar Tetap

Menghuraikan fail lebar tetap, di mana setiap lajur menduduki bilangan aksara tertentu dalam satu baris, boleh menjadi tugas yang memerlukan kecekapan. Berikut ialah perbincangan tentang cara untuk mencapai ini dengan cekap:

Masalahnya

Pertimbangkan fail lebar tetap di mana 20 aksara pertama mewakili satu lajur, diikuti dengan 21-30 untuk yang kedua, dan seterusnya pada. Memandangkan baris dengan 100 aksara, bagaimanakah kita boleh menghuraikannya dengan berkesan ke dalam lajur masing-masing?

Penyelesaian

1. Modul Struktur:

Menggunakan modul struktur perpustakaan standard Python memberikan kedua-dua kesederhanaan dan kelajuan kerana pelaksanaan Cnya. Kod di bawah menunjukkan penggunaannya:

<code class="python">import struct

fieldwidths = (2, -10, 24)
fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's') for fw in fieldwidths)

# Convert Unicode input to bytes and decode result.
unpack = struct.Struct(fmtstring).unpack_from  # Alias.
parse = lambda line: tuple(s.decode() for s in unpack(line.encode()))

# Parse a sample line.
line = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n'
fields = parse(line)
print('fields:', fields)</code>

Output:

fmtstring: '2s 10x 24s', record size: 36 chars
fields: ('AB', 'MNOPQRSTUVWXYZ0123456789')

2. Menghiris Rentetan Dioptimumkan:

Walaupun menghiris rentetan biasa digunakan, ia boleh menjadi menyusahkan untuk garisan besar. Berikut ialah pendekatan yang dioptimumkan:

<code class="python">from itertools import zip_longest
from itertools import accumulate

def make_parser(fieldwidths):
    # Calculate slice boundaries.
    cuts = tuple(cut for cut in accumulate(abs(fw) for fw in fieldwidths))
    # Create field slice tuples.
    flds = tuple(zip_longest(cuts, (0,)+cuts))[:-1]  # Ignore final value.
    # Construct the parsing function.
    parse = lambda line: tuple(line[i:j] for i, j in flds)
    parse.size = sum(abs(fw) for fw in fieldwidths)
    parse.fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's')
                                            for fw in fieldwidths)
    return parse

# Parse a sample line.
line = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n'
fieldwidths = (2, -10, 24)  # Negative values indicate ignored padding fields.
parse = make_parser(fieldwidths)
fields = parse(line)
print('fmtstring:', parse.fmtstring, ', record size:', parse.size, 'chars')
print('fields:', fields)</code>

Output:

fmtstring: '2s 10x 24s', record size: 36 chars
fields: ('AB', 'MNOPQRSTUVWXYZ0123456789')

Atas ialah kandungan terperinci Bagaimanakah saya boleh menghuraikan baris fail lebar tetap dengan cekap dalam Python?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn