Saya menemukan skrip Python bernama transpose_file.py yang dapat mentranspos file yang dibatasi ruang. Ini terlihat seperti:

 import fileinput

 m = []
 for line in fileinput.input():
     m.append(line.strip().split(" "))
 for row in zip(*m):
     print " ".join(row)

Saya ingin memastikan bahwa saya memahami apa yang dilakukan setiap baris, karena saya sangat baru di Python.

1) Pertama, kami mengimpor modul bernama fileinput yang memungkinkan Anda membaca file dan menguraikannya? Tidak yakin mengapa menggunakan sederhana dengan open(sys.argv[1],'r') sebagai f dll tidak akan berfungsi

2) Buat daftar kosong yang disebut m

3) Untuk setiap baris dalam file input Anda, hapus spasi, tab, atau baris baru di akhir baris, dan buat spasi sebagai pembatas (yaitu file input Anda dibatasi)

4) Untuk setiap baris ... tidak yakin apa artinya sisanya. Apa artinya zip(*m)? Setelah ini selesai, kami mencetak spasi dan bergabung dengan baris? Saya hanya tidak melihat bagaimana ini menghasilkan transposisi.

Penjelasan apa pun akan sangat dihargai.

0
mf94 18 Oktober 2017, 17:43

2 jawaban

Jawaban Terbaik
  1. fileinput juga mendukung metode input file lainnya. Itu dapat secara efektif melakukan open(sys.argv[1],'r'), tetapi juga mendukung kemungkinan lain - lihat dokumentasi Python untuk ini.

  2. Pemahaman Anda tentang 2 dan 3 secara luas benar

  3. Untuk setiap baris, garis dilucuti dari spasi dan kemudian dipisahkan dengan spasi. Ini menghasilkan kisi yang mewakili setiap bagian file yang dibatasi spasi.

  4. zip(*) secara efektif adalah operator transposisi Python. Sebagai contoh:

    In [1]: data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    
    In [2]: data
    Out[2]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    
    In [3]: transp = list(zip(*data))
    
    In [4]: transp
    Out[4]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
    

    Anda harus memaksanya ke list karena zip mengembalikan iterable. zip mungkin lebih umum digunakan untuk "zip" bersama dua daftar, sehingga Anda dapat mengulanginya bersama-sama:

    In [1]: list(zip(["one", "three", "five"], ["two", "four", "six"]))
    Out[1]: [('one', 'two'), ('three', 'four'), ('five', 'six')]
    

    Ini juga didokumentasikan.

    Operator * memisahkan setiap subdaftar kisi menjadi argumen terpisah untuk zip.

    " ".join bergabung bersama setiap string dalam iterable dengan spasi - mis

    In [1]: " ".join(["foo", "bar", "baz"])
    Out[1]: 'foo bar baz'
    

    Ini hanya menempatkan pembatas ruang kembali ke rangkaian string Anda yang baru dialihkan. Sekali lagi, didokumentasikan.

1
Izaak van Dongen 18 Oktober 2017, 15:01

Analisis Anda pada dasarnya benar.

Perhatikan bahwa

line.strip().split(" ")

Sedikit rapuh. Ini menghapus semua spasi putih awal & akhir dari baris, dan kemudian membagi baris menjadi daftar string, menggunakan satu spasi sebagai pembatas. Ini mungkin tidak melakukan apa yang Anda inginkan jika baris berisi lebih dari satu spasi, atau jika berisi tab.


Fungsi zip mengulangi argumennya secara paralel, membangun tupel dari item yang sesuai di setiap argumen. Jadi pertama itu menghasilkan Tuple dari semua item pertama, lalu semua item kedua, dll.

Misalnya:

for t in zip([1, 2, 3], [4, 5, 6], [7, 8, 9]):
    print(t)
print()

keluaran

(1, 4, 7)
(2, 5, 8)
(3, 6, 9)

Seperti yang Anda lihat, ini menghasilkan transposisi.

Kita dapat menggunakan operator "splat" * untuk meneruskan daftar urutan ke zip, operator "splat" membongkar daftar sehingga zip melihat setiap urutan tersebut sebagai argumen terpisah .

lst = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

for t in zip(*lst):
    print(t)

Ini memberikan output yang sama seperti sebelumnya.

Operator "splat" bukan hanya fitur khusus zip: Anda dapat menggunakannya pada fungsi apa pun yang membutuhkan banyak argumen. Ada juga operator "percikan ganda" **, yang membongkar kamus menjadi pasangan kata kunci=nilai.

Jika urutannya berbeda panjangnya maka zip berhenti ketika tidak ada lagi item yang tersisa dalam urutan terpendek. Namun, ada fungsi terkait dalam modul itertools standar: itertools.zip_longest, yang menggunakan fillvalue opsional. Itu terus berjalan sampai urutan terpanjang habis, menggunakan fillvalue untuk mengisi celah. Defaultnya fillvalue adalah None.


Sehubungan dengan fileinput, beberapa orang hanya merasa nyaman, saya lebih suka with open(...

1
PM 2Ring 18 Oktober 2017, 15:02