Bagaimana cara membaca setiap baris file dengan Python dan menyimpan setiap baris sebagai elemen dalam daftar?
Saya ingin membaca file baris demi baris dan menambahkan setiap baris ke akhir daftar.
with open(filename) as f:
content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content]
file.readlines()
dalamfor
-loop, objek file itu sendiri sudah cukup:lines = [line.rstrip('\n') for line in file]
readlines()
tidak sangat efisien karena dapat mengakibatkan MemoryError . Dalam hal ini lebih baik untuk beralih menggunakan filefor line in f:
dan bekerja dengan masing-masingline
variabel..rstrip()
akan bekerja sedikit lebih cepat jika Anda membuka spasi dari ujung garis.with open(filename) as f: content = [i.strip() for i in f.readlines()]
Lihat Input dan Ouput :
atau dengan stripping karakter baris baru:
sumber
f.read().splitlines()
, yang menghapus baris barufor line in open(filename)
aman? Yaitu, apakah file akan ditutup secara otomatis?lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]
Jika saya menulis seperti ini, bagaimana saya bisa menutup file setelah membaca?open
tanpa manajer konteks (atau cara lain yang dijamin untuk menutupnya), ini sebenarnya bukan salah satu dari kasus tersebut - ketika objek tidak memiliki referensi lagi untuk itu akan menjadi sampah yang dikumpulkan dan file ditutup, yang seharusnya terjadi segera karena kesalahan atau tidak, ketika pemahaman daftar selesai diproses.Ini lebih eksplisit daripada yang diperlukan, tetapi lakukan apa yang Anda inginkan.
sumber
array
, tetapi mungkin ada keadaan lain). Tentu saja untuk file besar pendekatan ini dapat mengurangi masalah.Ini akan menghasilkan "array" baris dari file.
open
mengembalikan file yang dapat diulangi. Ketika Anda mengulangi file, Anda mendapatkan garis dari file itu.tuple
dapat mengambil iterator dan instantiate instance tuple untuk Anda dari iterator yang Anda berikan.lines
adalah tuple yang dibuat dari baris file.sumber
lines = open(filename).read().split('\n')
sebagai gantinya.lines = open(filename).read().splitlines()
sedikit lebih bersih, dan saya percaya itu juga menangani akhir baris DOS yang lebih baik.list
memakan sekitar 13,22% lebih banyak ruang daripada atuple
. Hasil datang darifrom sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2)
. Menciptakantuple
membutuhkan waktu sekitar 4,17% lebih banyak waktu daripada membuatlist
(dengan standar deviasi 0,16%). Hasil datang dari menjalankanfrom timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)
30 kali. Solusi saya mendukung ruang lebih dari kecepatan ketika kebutuhan untuk berubah tidak diketahui.Jika Anda ingin yang
\n
disertakan:Jika Anda tidak ingin
\n
disertakan:sumber
Menurut Metode File Objek Python , cara paling sederhana untuk mengubah file teks menjadi
list
:Jika Anda hanya perlu mengulangi baris file teks, Anda dapat menggunakan:
Jawaban lama:
Menggunakan
with
danreadlines()
:Jika Anda tidak peduli tentang penutupan file, one-liner ini berfungsi:
Cara tradisional :
sumber
Anda dapat melakukan hal berikut, seperti yang disarankan:
Perhatikan bahwa pendekatan ini memiliki 2 kelemahan:
1) Anda menyimpan semua baris dalam memori. Dalam kasus umum, ini adalah ide yang sangat buruk. File bisa sangat besar, dan Anda bisa kehabisan memori. Bahkan jika itu tidak besar, itu hanya membuang-buang memori.
2) Ini tidak memungkinkan pemrosesan setiap baris saat Anda membacanya. Jadi, jika Anda memproses baris Anda setelah ini, itu tidak efisien (membutuhkan dua lintasan daripada satu).
Pendekatan yang lebih baik untuk kasus umum adalah sebagai berikut:
Di mana Anda mendefinisikan fungsi proses Anda dengan cara apa pun yang Anda inginkan. Sebagai contoh:
(Implementasi dari
Superman
kelas dibiarkan sebagai latihan untuk Anda).Ini akan bekerja dengan baik untuk ukuran file apa pun dan Anda pergi melalui file Anda hanya dalam 1 pass. Ini biasanya bagaimana parser generik akan bekerja.
sumber
open('file_path', 'r+')
Data menjadi daftar
Anggap kita memiliki file teks dengan data kita seperti pada baris berikut,
Konten file teks:
python
dan tulis dalam interpreter:Skrip Python:
Menggunakan menambahkan:
Atau:
Atau:
Atau:
keluaran:
sumber
read().splitlines()
disediakan untuk Anda oleh Python: itu sederhanareadlines()
(yang mungkin lebih cepat, karena kurang boros).read().splitlines()
danreadlines()
tidak menghasilkan output yang sama. Apakah Anda yakin mereka setara?strip()
seharusnyarstrip("\n")
atau spasi di sekitar baris dihapus. Juga, tidak ada gunanya melakukanreadlines()
dalam pemahaman daftar: hanya iterasi file lebih baik, karena tidak membuang waktu dan memori dengan membuat daftar perantara baris.Untuk membaca file ke dalam daftar, Anda perlu melakukan tiga hal:
Untungnya Python membuatnya sangat mudah untuk melakukan hal-hal ini sehingga cara terpendek untuk membaca file ke dalam daftar adalah:
Namun saya akan menambahkan beberapa penjelasan.
Membuka file
Saya berasumsi bahwa Anda ingin membuka file tertentu dan Anda tidak berurusan langsung dengan file-handle (atau file-like-handle). Fungsi yang paling umum digunakan untuk membuka file dalam Python adalah
open
, dibutuhkan satu argumen wajib dan dua opsional dalam Python 2.7:Nama file harus berupa string yang mewakili jalur ke file . Sebagai contoh:
Perhatikan bahwa ekstensi file perlu ditentukan. Ini sangat penting bagi pengguna Windows karena ekstensi file seperti
.txt
atau.doc
, dll. Disembunyikan secara default ketika dilihat di explorer.Argumen kedua adalah
mode
, inir
secara default yang berarti "hanya-baca". Itulah tepatnya yang Anda butuhkan dalam kasus Anda.Tetapi jika Anda benar-benar ingin membuat file dan / atau menulis ke file Anda akan memerlukan argumen yang berbeda di sini. Ada jawaban yang sangat bagus jika Anda ingin ikhtisar .
Untuk membaca file, Anda dapat menghilangkan
mode
atau meneruskannya secara eksplisit:Keduanya akan membuka file dalam mode read-only. Jika Anda ingin membaca dalam file biner pada Windows Anda perlu menggunakan mode
rb
:Pada platform lain,
'b'
(mode biner) diabaikan.Sekarang saya telah menunjukkan cara ke
open
file, mari kita bicara tentang fakta bahwa Anda selalu membutuhkannyaclose
lagi. Kalau tidak, ia akan menyimpan file-handle yang terbuka ke file sampai proses keluar (atau Python membuat file-handle).Meskipun Anda dapat menggunakan:
Itu akan gagal untuk menutup file ketika ada sesuatu di antara
open
danclose
melempar pengecualian. Anda bisa menghindarinya dengan menggunakan atry
danfinally
:Namun Python menyediakan manajer konteks yang memiliki sintaks cantik (tapi untuk
open
itu hampir identik dengantry
danfinally
atas):Pendekatan terakhir adalah yang direkomendasikan untuk membuka file dengan Python!
Membaca file
Oke, Anda sudah membuka file, sekarang bagaimana cara membacanya?
The
open
mengembalikan fungsifile
objek dan mendukung Piton protokol iterasi. Setiap iterasi akan memberi Anda garis:Ini akan mencetak setiap baris file. Perhatikan bahwa setiap baris akan berisi karakter baris baru
\n
di bagian akhir (Anda mungkin ingin memeriksa apakah Python Anda dibangun dengan dukungan baris baru universal - jika tidak, Anda juga bisa\r\n
menggunakan Windows atau\r
Mac sebagai baris baru). Jika Anda tidak mau, Anda bisa menghapus karakter terakhir (atau dua karakter terakhir di Windows):Tapi baris terakhir tidak harus memiliki baris baru, jadi jangan gunakan itu. Orang dapat memeriksa apakah itu berakhir dengan baris baru tambahan dan jika demikian hapus:
Tapi Anda hanya bisa menghapus semua spasi putih (termasuk
\n
karakter) dari akhir string , ini juga akan menghapus semua lainnya Trailing spasi putih sehingga Anda harus berhati-hati jika ini penting:Namun jika garis berakhir dengan
\r\n
(Windows "baris baru") yang.rstrip()
juga akan mengurus\r
!Simpan konten sebagai daftar
Sekarang setelah Anda tahu cara membuka file dan membacanya, saatnya untuk menyimpan konten dalam daftar. Opsi paling sederhana adalah menggunakan
list
fungsi:Jika Anda ingin menghapus baris baru, Anda bisa menggunakan pemahaman daftar sebagai gantinya:
Atau bahkan lebih sederhana:
.readlines()
Metodefile
objek secara default mengembalikan alist
dari baris:Ini juga akan menyertakan karakter baris baru yang tertinggal, jika Anda tidak menginginkannya, saya akan merekomendasikan
[line.rstrip() for line in f]
pendekatan karena menghindari menyimpan dua daftar yang berisi semua baris dalam memori.Ada opsi tambahan untuk mendapatkan output yang diinginkan, namun ini agak "suboptimal":
read
file lengkap dalam sebuah string dan kemudian dibagi pada baris baru:atau:
Ini menangani baris baru yang tertinggal secara otomatis karena
split
karakter tidak termasuk. Namun mereka tidak ideal karena Anda menyimpan file sebagai string dan sebagai daftar baris dalam memori!Ringkasan
with open(...) as f
saat membuka file karena Anda tidak perlu mengurus sendiri penutupan file dan menutup file bahkan jika beberapa pengecualian terjadi.file
objek mendukung protokol iterasi sehingga membaca file baris demi baris sesederhanafor line in the_file_object:
.readlines()
tetapi jika Anda ingin memproses baris sebelum menyimpannya dalam daftar, saya akan merekomendasikan daftar-pemahaman sederhana.sumber
Cara Bersih dan Pythonic Membaca Garis-Garis File Menjadi Daftar
Pertama dan terutama, Anda harus fokus pada membuka file Anda dan membaca isinya dengan cara yang efisien dan pythonic. Ini adalah contoh dari cara yang secara pribadi TIDAK Saya sukai:
Sebaliknya, saya lebih suka metode membuka file di bawah ini untuk membaca dan menulis karena sangat bersih, dan tidak memerlukan langkah tambahan untuk menutup file setelah Anda selesai menggunakannya. Dalam pernyataan di bawah ini, kami membuka file untuk dibaca, dan menugaskannya ke variabel 'infile.' Setelah kode dalam pernyataan ini selesai berjalan, file akan ditutup secara otomatis.
Sekarang kita perlu fokus untuk membawa data ini ke dalam Daftar Python karena mereka dapat diubah, efisien, dan fleksibel. Dalam kasus Anda, tujuan yang diinginkan adalah untuk membawa setiap baris file teks ke elemen yang terpisah. Untuk mencapai ini, kami akan menggunakan metode splitlines () sebagai berikut:
Produk Akhir:
Menguji Kode Kami:
sumber
Diperkenalkan dalam Python 3.4,
pathlib
memiliki metode yang sangat nyaman untuk membaca teks dari file, sebagai berikut:(
splitlines
Panggilan inilah yang mengubahnya dari string yang berisi seluruh isi file ke daftar baris dalam file).pathlib
memiliki banyak kenyamanan praktis di dalamnya.read_text
bagus dan ringkas, dan Anda tidak perlu khawatir tentang membuka dan menutup file. Jika semua yang perlu Anda lakukan dengan file tersebut adalah membacanya semuanya sekaligus, itu adalah pilihan yang baik.sumber
Berikut ini satu opsi lagi dengan menggunakan daftar pemahaman pada file;
Ini harus menjadi cara yang lebih efisien karena sebagian besar pekerjaan dilakukan di dalam juru bahasa Python.
sumber
rstrip()
berpotensi menghapus semua spasi spasi, tidak hanya\n
; gunakan.rstrip('\n')
.Sekarang variabel keluar adalah daftar (array) dari apa yang Anda inginkan. Anda bisa melakukan:
Atau:
Anda akan mendapatkan hasil yang sama.
sumber
Baca dan tulis file teks dengan Python 2 dan Python 3; ini bekerja dengan Unicode
Hal-hal yang perlu diperhatikan:
with
adalah yang disebut manajer konteks . Itu memastikan bahwa file yang dibuka ditutup lagi..strip()
atau.rstrip()
akan gagal mereproduksilines
karena mereka juga menghilangkan ruang putih.Ujung file umum
.txt
Penulisan / pembacaan file lebih lanjut
Untuk aplikasi Anda, berikut ini mungkin penting:
Lihat juga: Perbandingan format serialisasi data
Jika Anda lebih suka mencari cara untuk membuat file konfigurasi, Anda mungkin ingin membaca artikel pendek saya File konfigurasi dalam Python .
sumber
Pilihan lain adalah
numpy.genfromtxt
, misalnya:Ini akan membuat
data
array NumPy dengan sebanyak mungkin baris dalam file Anda.sumber
Jika Anda ingin membaca file dari baris perintah atau dari stdin, Anda juga dapat menggunakan
fileinput
modul:Lewati file seperti itu:
Baca lebih lanjut di sini: http://docs.python.org/2/library/fileinput.html
sumber
Cara paling sederhana untuk melakukannya
Cara sederhana adalah dengan:
Dalam satu baris, itu akan memberi:
Namun, ini cara yang tidak efisien karena ini akan menyimpan 2 versi konten dalam memori (mungkin bukan masalah besar untuk file kecil, tapi tetap saja). [Terima kasih, Mark Amery].
Ada 2 cara yang lebih mudah:
pathlib
untuk membuat jalur untuk file Anda yang bisa Anda gunakan untuk operasi lain dalam program Anda:sumber
.read().splitlines()
sama sekali tidak "sederhana" dari sekadar menelepon.readlines()
. Untuk yang lain, itu tidak efisien dalam memori; Anda tidak perlu menyimpan dua versi konten file (string tunggal yang dikembalikan oleh.read()
, dan daftar string yang dikembalikan olehsplitlines()
) dalam memori sekaligus.Cukup gunakan fungsi splitlines (). Berikut ini sebuah contoh.
Dalam output Anda akan memiliki daftar baris.
sumber
.readlines()
. Ini menempatkan dua salinan isi file dalam memori sekaligus (satu sebagai string besar, satu sebagai daftar baris).Jika Anda ingin dihadapkan dengan file yang sangat besar / besar dan ingin membaca lebih cepat (bayangkan Anda berada dalam kompetisi pengkodean Topcoder / Hackerrank), Anda mungkin membaca sepotong baris yang jauh lebih besar ke buffer memori pada satu waktu, daripada iterate baris demi baris di tingkat file.
sumber
process(line)
adalah fungsi yang perlu Anda terapkan untuk memproses data. misalnya, alih-alih baris itu, jika Anda gunakanprint(line)
, itu akan mencetak setiap baris dari lines_buffer.Cara termudah untuk melakukannya dengan beberapa manfaat tambahan adalah:
atau
atau
Dalam hal ini
set
, kita harus diingat bahwa kita tidak memiliki urutan garis yang dipertahankan dan menyingkirkan garis yang digandakan.Di bawah ini saya menambahkan suplemen penting dari @MarkAmery :
sumber
.close
objek file atau menggunakanwith
pernyataan, dalam beberapa implementasi Python file mungkin tidak akan ditutup setelah membaca dan proses Anda akan bocor menangani file yang terbuka. Dalam CPython (implementasi Python normal yang kebanyakan orang gunakan), ini bukan masalah karena objek file akan segera mengumpulkan sampah dan ini akan menutup file, tetapi tetap dianggap praktik terbaik untuk melakukan sesuatu sepertiwith open('filename') as f: lines = list(f)
memastikan bahwa file akan ditutup terlepas dari apa implementasi Python yang Anda gunakan.Gunakan ini:
data
adalah tipe dataframe, dan menggunakan nilai untuk mendapatkan ndarray. Anda juga bisa mendapatkan daftar dengan menggunakanarray.tolist()
.sumber
pandas.read_csv()
adalah untuk membaca data CSV , bagaimana cara tepat di sini?Garis Besar dan Ringkasan
Dengan
filename
, menangani file dariPath(filename)
objek, atau langsung denganopen(filename) as f
, lakukan salah satu hal berikut ini:list(fileinput.input(filename))
with path.open() as f
, hubungif.readlines()
list(f)
path.read_text().splitlines()
path.read_text().splitlines(keepends=True)
fileinput.input
atauf
danlist.append
setiap baris satu per satuf
kelist.extend
metode terikatf
dalam pemahaman daftarSaya jelaskan use-case untuk masing-masing di bawah ini.
Ini adalah pertanyaan yang sangat bagus. Pertama, mari kita buat beberapa data sampel:
File objek adalah iterator yang malas, jadi lakukan iterate saja.
Atau, jika Anda memiliki banyak file, gunakan
fileinput.input
, iterator malas lainnya. Hanya dengan satu file:atau untuk banyak file, berikan daftar nama file:
Sekali lagi,
f
dan difileinput.input
atas keduanya adalah / kembali iterators malas. Anda hanya dapat menggunakan iterator satu kali, jadi untuk memberikan kode fungsional sambil menghindari verbositas, saya akan menggunakan sedikit lebih singkat difileinput.input(filename)
mana apropos dari sini.Ah, tetapi Anda menginginkannya dalam daftar karena suatu alasan? Saya akan menghindari itu jika memungkinkan. Tetapi jika Anda bersikeras ... sampaikan saja
fileinput.input(filename)
kepadalist
:Jawaban langsung lainnya adalah menelepon
f.readlines
, yang mengembalikan konten file (hinggahint
sejumlah karakter opsional , sehingga Anda dapat memecahnya menjadi beberapa daftar dengan cara itu).Anda bisa mendapatkan objek file ini dengan dua cara. Salah satu caranya adalah meneruskan nama file ke
open
builtin:atau menggunakan objek Path baru dari
pathlib
modul (yang telah saya sukai, dan akan digunakan mulai sekarang):list
juga akan mengkonsumsi file iterator dan mengembalikan daftar - metode yang cukup langsung:Jika Anda tidak keberatan membaca seluruh teks ke dalam memori sebagai string tunggal sebelum membaginya, Anda dapat melakukan ini sebagai satu-baris dengan
Path
objek dansplitlines()
metode string. Secara default,splitlines
hapus baris baru:Jika Anda ingin mempertahankan baris baru, sampaikan
keepends=True
:Sekarang ini agak konyol untuk bertanya, mengingat bahwa kami telah menunjukkan hasil akhirnya dengan mudah dengan beberapa metode. Tetapi Anda mungkin perlu memfilter atau mengoperasikan saluran saat Anda membuat daftar, jadi mari kita selesaikan permintaan ini.
Menggunakan
list.append
akan memungkinkan Anda untuk memfilter atau beroperasi pada setiap baris sebelum Anda menambahkannya:Penggunaan
list.extend
akan sedikit lebih langsung, dan mungkin berguna jika Anda memiliki daftar yang sudah ada sebelumnya:Atau lebih secara idiomatis, kita bisa menggunakan pemahaman daftar, dan memetakan dan memfilter di dalamnya jika diinginkan:
Atau bahkan lebih langsung, untuk menutup lingkaran, cukup kirimkan ke daftar untuk membuat daftar baru secara langsung tanpa beroperasi pada garis:
Kesimpulan
Anda telah melihat banyak cara untuk mendapatkan baris dari file ke dalam daftar, tetapi saya sarankan Anda menghindari mematerialisasi data dalam jumlah besar ke dalam daftar dan alih-alih menggunakan iterasi malas Python untuk memproses data jika memungkinkan.
Yaitu, lebih suka
fileinput.input
atauwith path.open() as f
.sumber
Dalam hal ada juga baris kosong di dokumen saya suka membaca konten dan meneruskannya
filter
untuk mencegah elemen string kosongsumber
Anda juga bisa menggunakan perintah loadtxt di NumPy. Ini memeriksa kondisi yang lebih sedikit daripada genfromtxt, jadi mungkin lebih cepat.
sumber
Saya suka menggunakan yang berikut ini. Segera baca dialognya.
Atau menggunakan pemahaman daftar:
sumber
readlines()
, yang bahkan menimbulkan hukuman memori. Anda cukup menghapusnya, karena iterasi file (teks) memberikan setiap baris pada gilirannya.with
pernyataan untuk membuka (dan secara implisit menutup) file tersebut.Saya akan mencoba salah satu metode yang disebutkan di bawah ini. Contoh file yang saya gunakan memiliki nama
dummy.txt
. Anda dapat menemukan file di sini . Saya kira, file tersebut berada di direktori yang sama dengan kode (Anda dapat mengubahfpath
untuk memasukkan nama file dan jalur folder yang tepat.)Dalam kedua contoh yang disebutkan di bawah ini, daftar yang Anda inginkan diberikan oleh
lst
.1.> Metode pertama :
2.> Pada metode kedua , seseorang dapat menggunakan modul csv.reader dari Python Standard Library :
Anda dapat menggunakan salah satu dari dua metode ini. Waktu yang dibutuhkan untuk pembuatan
lst
hampir sama dalam dua metode.sumber
delimiter=' '
argumennya?Berikut adalah kelas
pustakapembantu Python (3) yang saya gunakan untuk menyederhanakan file I / O:Anda kemudian akan menggunakan
FileIO.lines
fungsinya, seperti ini:Ingat bahwa parameter
mode
("r"
secara default) danfilter_fn
(memeriksa jalur kosong secara default) adalah opsional.Anda bahkan dapat menghapus
read
,write
dandelete
metode dan hanya meninggalkanFileIO.lines
, atau bahkan mengubahnya menjadi metode terpisah yang disebutread_lines
.sumber
lines = FileIO.lines(path)
benar-benar cukup sederhana daripadawith open(path) as f: lines = f.readlines()
membenarkan keberadaan penolong ini? Anda menyimpan, misalnya, 17 karakter per panggilan. (Dan sebagian besar waktu, untuk alasan kinerja dan memori, Anda ingin melompati objek file secara langsung alih-alih membaca barisnya menjadi daftar, sehingga Anda bahkan tidak ingin sering menggunakan ini!) Saya sering penggemar membuat sedikit fungsi utilitas, tetapi yang ini terasa bagi saya seperti itu hanya perlu menciptakan cara baru untuk menulis sesuatu yang sudah pendek dan mudah dengan perpustakaan standar memberi kita.Versi baris perintah
Jalankan dengan:
sumber