Bir dosyayı bir satır satır listeye nasıl okursunuz?


2027

Python'daki bir dosyanın her satırını nasıl okurum ve her satırı bir listede öğe olarak nasıl depolayabilirim?

Dosyayı satır satır okumak ve her satırı listenin sonuna eklemek istiyorum.

Yanıtlar:


2174
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] 

206
file.readlines()Bir for-loop'ta kullanmayın , bir dosya nesnesinin kendisi yeterlidir:lines = [line.rstrip('\n') for line in file]
jfs

88
Büyük Veri ile çalışmanız durumunda MemoryError ilereadlines() sonuçlanabileceğinden kullanımı çok verimli değildir . Bu durumda , her değişkeni kullanarak ve üzerinde çalışarak dosyayı yinelemek daha iyidir . for line in f:line
DarkCygnus

7
Burada belirtilen prosedürü kullanarak cevaplarda verilen farklı yolların hafıza profilini kontrol ettim . Bellek kullanımı @DevShark önerdiği gibi her bir satır, dosyadan okuma ve işlendiğinde çok daha iyi olduğunu burada . Bellek bir kısıtlama veya dosya büyükse , bir koleksiyon nesnesindeki tüm satırları tutmak iyi bir fikir değildir . Uygulama süresi her iki yaklaşımda da benzerdir.
Tirtha R

6
Ayrıca, .rstrip()boşlukların satır sonlarından çıkarılması durumunda biraz daha hızlı çalışacaktır.
Gringo Suave

Oneliner:with open(filename) as f: content = [i.strip() for i in f.readlines()]
Vishal Gupta

1002

Bkz. Giriş ve Çıkış :

with open('filename') as f:
    lines = f.readlines()

veya yeni satır karakterini sıyırma yoluyla:

with open('filename') as f:
    lines = [line.rstrip() for line in f]

12
Daha iyi, kullanım f.read().splitlines(), yeni satırları kaldırır
Mark

İkinci sürüm for line in open(filename)güvenli mi? Yani, dosya otomatik olarak kapatılacak mı?
becko

2
Tüm dosyayı bir kerede belleğe okumak yerine bir kerede bir satır okumak en iyisidir. Bunu yapmak büyük girdi dosyalarıyla iyi ölçeklenmez. Robert'ın cevabına bakınız.
Brad Hein

1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]Bu şekilde yazarsam, okuduktan sonra dosyayı nasıl kapatabilirim?
Ramisa Anjum Aditi

2
Evet, başkalarının burada yaptığı noktaya göre open, bağlam yöneticisi (veya kapatmak için başka bir garantili yol) olmadan kullanmak "en iyi uygulama" olmasa da, bu gerçekten bu durumlardan biri değil - nesnenin daha fazla referansı olmadığında bunun için, liste kavraması işlendiğinde derhal hata olması ya da olmaması gereken çöp toplanacak ve dosya kapatılacaktır.
Aaron Hall

579

Bu gerekenden daha belirgindir, ancak ne istersen yapar.

with open("file.txt") as file_in:
    lines = []
    for line in file_in:
        lines.append(line)

18
Tüm dosyayı belleğe yüklemeyi gerektirmediği için bu cevabı tercih ederim (bu durumda yine de eklenir array, ancak başka durumlar olabilir). Kesinlikle büyük dosyalar için bu yaklaşım sorunları azaltabilir.
JohannesB

1
Bir diziye ekleme yavaş. Bunun en iyi çözüm olduğu bir kullanım durumu düşünemiyorum.
Elias Strehle

@haccks daha iyi çünkü tüm dosyayı belleğe yüklemiyor veya daha fazlası var mı?
OrigamiEye

4
Not: Bu çözüm yeni satırları çıkarmaz.
AMC

1
Bu çözüm tüm dosyayı belleğe yükler. İnsanların neden böyle düşünmediğini bilmiyorum.
andrebrait

274

Bu, dosyadan bir "dizi" satırı verecektir.

lines = tuple(open(filename, 'r'))

openüzerinden yinelenebilen bir dosya döndürür. Bir dosya üzerinde yineleme yaptığınızda, bu dosyadan satır alırsınız. tuplebir yineleyici alabilir ve verdiğin yineleyiciden sizin için bir tuple örneği başlatabilir. lines, dosyanın satırlarından oluşturulan bir demettir.


31
@MarshallFarrier lines = open(filename).read().split('\n')Bunun yerine deneyin .
Noctis Skytower

16
dosyayı kapatıyor mu?
Vanuan

5
@Vanuan Yıkıcı, çalıştırılan satırdan sonra dosyaya hiçbir kalan referans olmadığı için gerektiği otomatik olarak kapanacak dosyası.
Noctis Skytower

30
@NoctisSkytower lines = open(filename).read().splitlines()Biraz daha temiz buluyorum ve ayrıca DOS satır sonlarını daha iyi işlediğine inanıyorum.
jaynp

8
@ mklement0 1000 satırlık bir dosya varsayarsak, a list, a'dan yaklaşık% 13,22 daha fazla yer kaplar tuple. Sonuçlar from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2). Oluşturmak, oluşturmaktan tuple% 4.17 daha fazla zaman alır list(% 0.16 standart sapma ile). Sonuçlar from timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)30 kez yayınlanmaktadır . Değişime ihtiyaç duyulmadığında çözümüm hızdan fazla alan sağlıyor.
Noctis Skytower

194

\nDahil etmek istiyorsanız :

with open(fname) as f:
    content = f.readlines()

\nDahil etmek istemiyorsanız :

with open(fname) as f:
    content = f.read().splitlines()

168

Python'un Dosya Nesneleri Yöntemlerine göre , bir metin dosyasını a dönüştürmenin en basit yolu list:

with open('file.txt') as f:
    my_list = list(f)

Metin dosyası satırları üzerinden yineleme yapmanız gerekirse, şunları kullanabilirsiniz:

with open('file.txt') as f:
    for line in f:
       ...

Eski cevap:

Kullanılması withve readlines():

with open('file.txt') as f:
    lines = f.readlines()

Dosyayı kapatmayı umursamıyorsanız, bu tek astar çalışır:

lines = open('file.txt').readlines()

Geleneksel yol:

f = open('file.txt') # Open file on read mode
lines = f.read().split("\n") # Create a list containing all lines
f.close() # Close file

150

Önerildiği gibi şunları yapabilirsiniz:

with open('/your/path/file') as f:
    my_lines = f.readlines()

Bu yaklaşımın 2 dezavantajı olduğunu unutmayın:

1) Tüm satırları hafızaya kaydedersiniz. Genel durumda, bu çok kötü bir fikir. Dosya çok büyük olabilir ve belleğiniz bitebilir. Büyük olmasa bile, sadece bir bellek kaybıdır.

2) Bu, her satırı okurken işlemeye izin vermez. Bundan sonra hatlarınızı işlerseniz, verimli değildir (bir değil iki geçiş gerektirir).

Genel dava için daha iyi bir yaklaşım aşağıdaki gibidir:

with open('/your/path/file') as f:
    for line in f:
        process(line)

Proses fonksiyonunuzu istediğiniz şekilde tanımladığınız yer. Örneğin:

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

( SupermanSınıfın uygulanması sizin için bir alıştırma olarak bırakılmıştır).

Bu herhangi bir dosya boyutu için güzel çalışır ve sadece 1 geçişte dosya üzerinden gidersiniz. Bu genellikle genel ayrıştırıcıların çalışma biçimidir.


5
Bu tam olarak ihtiyacım olan şeydi - ve dezavantajları açıkladığınız için teşekkürler. Python'a yeni başlayan biri olarak, bir çözümün neden çözüm olduğunu anlamak harika. Şerefe!
Ephexx

5
Biraz daha düşün Corey. Bilgisayarınızın bu satırlarla hiçbir şey yapmadan her satırı okumasını gerçekten istiyor musunuz? Elbette onları her zaman şu ya da bu şekilde işlemeniz gerektiğini fark edebilirsiniz.
DevShark

5
Her zaman çizgilerle bir şeyler yapmalısınız. Çizgileri yazdırmak veya saymak kadar basit olabilir. İşleminizin bellekteki satırları okumasının bir değeri yoktur, ancak onunla hiçbir şey yapmazsınız.
DevShark

2
Onlarla her zaman bir şeyler yapmalısın. Sanırım anlatmaya çalıştığınız nokta, hepsine tek tek değil, bir kerede bir işlev uygulamak isteyebileceğinizdir. Gerçekten de bazen böyle olur. Ancak bellek açısından çok verimsizdir ve kapladığı alan RAM'inizden daha büyükse dosyaları okumanızı engeller. Bu yüzden genel olarak ayrıştırıcılar tanımladığım şekilde çalışır.
DevShark

2
@PierreOcinom doğru. Dosyanın salt okunur modda açıldığı göz önüne alındığında, orijinal dosyayı yukarıdaki kodla değiştiremezsiniz. Hem okuma hem de yazma için bir dosya açmak için şunu kullanın:open('file_path', 'r+')
DevShark

64

Listedeki veriler

Aşağıdaki satırlardaki gibi verilerimizle bir metin dosyamız olduğunu varsayalım,

Metin dosyası içeriği:

line 1
line 2
line 3
  • Cmd'yi aynı dizinde açın (fareye sağ tıklayın ve cmd veya PowerShell'i seçin)
  • Çalıştırın pythonve yorumlayıcıya şunu yazın:

Python betiği:

>>> with open("myfile.txt", encoding="utf-8") as file:
...     x = [l.strip() for l in file]
>>> x
['line 1','line 2','line 3']

Son kullanma:

x = []
with open("myfile.txt") as file:
    for l in file:
        x.append(l.strip())

Veya:

>>> x = open("myfile.txt").read().splitlines()
>>> x
['line 1', 'line 2', 'line 3']

Veya:

>>> x = open("myfile.txt").readlines()
>>> x
['linea 1\n', 'line 2\n', 'line 3\n']

Veya:

def print_output(lines_in_textfile):
    print("lines_in_textfile =", lines_in_textfile)

y = [x.rstrip() for x in open("001.txt")]
print_output(y)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = file.read().splitlines()
    print_output(file)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = [x.strip() for x in file.readlines()]
    print_output(file)

çıktı:

lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']

edilir encoding="utf-8"gerekli?
Mausy5043

@ Mausy5043 hayır, ancak bir metin dosyasını okuduğunuzda, garip bir karaktere sahip olabilirsiniz (özellikle italyanca)
Giovanni G. PY

1
read().splitlines()size Python tarafından sağlanır: basittir readlines()(muhtemelen daha az israf olduğundan daha hızlıdır).
Eric O Lebigot

@EricOLebigot gösterilen örneklerden aynı görünüyor read().splitlines()ve readlines()aynı çıktıyı üretmiyor. Eşdeğer olduklarından emin misiniz?
craq

Yalnızca okuma satırları kullanırsanız, metindeki \ n'den kurtulmak için strip yöntemini kullanmanız gerekir, bu nedenle her iki durumda da aynı çıktıya sahip olmak için bir liste kavrama kullanarak son örnekleri değiştirdim. Bu nedenle, read (). Readlines () kullanırsanız, satırla birlikte ve yeni satır karakteri olmadan "temiz" bir öğeye sahip olursunuz, aksi takdirde yukarıdaki kodda gördüklerinizi yapmalısınız.
Giovanni G. PY

43

Bir dosyayı bir listeye okumak için üç şey yapmanız gerekir:

  • Dosyayı aç
  • Dosyayı okuyun
  • İçeriği liste olarak sakla

Neyse ki Python bu şeyleri yapmayı çok kolaylaştırıyor, bu yüzden bir dosyayı bir listeye okumanın en kısa yolu:

lst = list(open(filename))

Ancak biraz daha açıklama ekleyeceğim.

Dosya açma

Belirli bir dosyayı açmak istediğinizi ve doğrudan bir dosya tanıtıcısı (veya dosya benzeri bir tanıtıcı) ile ilgilenmediğinizi varsayalım. Python'da bir dosyayı açmak için en sık kullanılan işlev open, bir zorunlu argüman ve Python 2.7'de iki isteğe bağlı argüman alır:

  • Dosya adı
  • kip
  • Arabelleğe alma (bu cevaptaki bu argümanı görmezden geleceğim)

Dosya adı , dosyanın yolunu temsil eden bir dize olmalıdır . Örneğin:

open('afile')   # opens the file named afile in the current working directory
open('adir/afile')            # relative path (relative to the current working directory)
open('C:/users/aname/afile')  # absolute path (windows)
open('/usr/local/afile')      # absolute path (linux)

Dosya uzantısının belirtilmesi gerektiğini unutmayın. Bu, özellikle Windows kullanıcıları için önemlidir, çünkü .txtveya .docvb. Dosya uzantıları explorer'da görüntülendiğinde varsayılan olarak gizlidir .

İkinci argüman ise modebu, raraçlar "salt okunur" varsayılan olarak. Tam da ihtiyacınız olan şey bu.

Ancak aslında bir dosya oluşturmak ve / veya bir dosyaya yazmak istiyorsanız, burada farklı bir argümana ihtiyacınız olacaktır. Genel bir bakış istiyorsanız mükemmel bir cevap var .

Bir dosyayı okumak için dosyayı atlayabilir modeveya açık bir şekilde iletebilirsiniz:

open(filename)
open(filename, 'r')

Her ikisi de dosyayı salt okunur modda açar. Windows'ta bir ikili dosyada okumak istiyorsanız, modu kullanmanız gerekir rb:

open(filename, 'rb')

Diğer platformlarda 'b'(ikili mod) yok sayılır.


Şimdi opendosyayı nasıl gösterdiğime göre , her zaman ihtiyacınız olan şey hakkında konuşalımclose ona tekrar . Aksi takdirde, işlem bitene kadar (veya Python dosya tanıtıcısını garbajlayana kadar) açık bir dosya tanıtıcısı tutar.

Kullanabileceğiniz halde:

f = open(filename)
# ... do stuff with f
f.close()

Bu, arasında bir şey olduğunda openve closebir istisna attığında dosyayı kapatmaz . A tryve finally: komutlarını kullanarak bundan kaçınabilirsiniz.

f = open(filename)
# nothing in between!
try:
    # do stuff with f
finally:
    f.close()

Ancak Python, daha güzel bir sözdizimine sahip içerik yöneticileri sağlar (ancak yukarıdaki ve openneredeyse neredeyse aynıdır ):tryfinally

with open(filename) as f:
    # do stuff with f
# The file is always closed after the with-scope ends.

Son yaklaşım Python'da bir dosya açmak için önerilen yaklaşımdır!

Dosyayı okuma

Tamam, dosyayı açtın, şimdi nasıl okunur?

openİşlev bir döner filenesne ve piton yineleme protokolünü destekler. Her yineleme size bir satır verecektir:

with open(filename) as f:
    for line in f:
        print(line)

Böylece dosyanın her satırı yazdırılır. Bununla birlikte, her satırın \nsonunda bir yeni satır karakteri içereceğini unutmayın (Python'unuzun evrensel yeni satır desteği ile oluşturulmuş olup olmadığını kontrol etmek isteyebilirsiniz - aksi takdirde \r\nWindows veya \rMac'te yeni satırlar da olabilir). Bunu istemiyorsanız, son karakteri (veya Windows'daki son iki karakteri) kaldırabilirsiniz:

with open(filename) as f:
    for line in f:
        print(line[:-1])

Ancak son satırın mutlaka sondaki bir yeni satırı yoktur, bu yüzden bunu kullanmamalıdır. Bir sondaki satırsonu ile bitip bitmediğini kontrol edebilir ve varsa kaldırabilirsiniz:

with open(filename) as f:
    for line in f:
        if line.endswith('\n'):
            line = line[:-1]
        print(line)

Ama sadece (dahil tüm boşlukları kaldırmak olabilir \ndan karakteriyle) dizenin sonuna , bu da tüm diğer kaldıracaktır sondaki bu önemli olup olmadığını dikkatli olmak zorunda boşlukları:

with open(filename) as f:
    for line in f:
        print(f.rstrip())

Ancak satırlar \r\n(Windows "newlines") ile bitiyorsa .rstrip(),\r !

İçeriği liste olarak sakla

Artık dosyayı nasıl açacağınızı ve okuyacağınızı bildiğinize göre, içeriği bir listede saklama zamanı. En basit seçenek listişlevi kullanmak olacaktır :

with open(filename) as f:
    lst = list(f)

Sondaki yeni satırları soymak istiyorsanız, bunun yerine bir liste kavrayışı kullanabilirsiniz:

with open(filename) as f:
    lst = [line.rstrip() for line in f]

Veya daha da basit: Nesnenin .readlines()yöntemi filevarsayılan listolarak satırlardan birini döndürür :

with open(filename) as f:
    lst = f.readlines()

Bu, sondaki yeni satır karakterlerini de içerecektir, eğer istemiyorsanız, [line.rstrip() for line in f] yaklaşımı çünkü tüm satırları içeren iki listeyi hafızada tutmaktan kaçınır.

İstenen çıktıyı elde etmek için ek bir seçenek vardır, ancak bunun yerine "yetersiz" dir: readbir dizedeki tüm dosya ve ardından yeni satırlara bölün:

with open(filename) as f:
    lst = f.read().split('\n')

veya:

with open(filename) as f:
    lst = f.read().splitlines()

Bunlar otomatik olarak sondaki yeni satırlarla ilgilenir, çünkü split karakter dahil edilmediğinden . Ancak ideal değildir, çünkü dosyayı dize olarak ve bellekteki satırların bir listesi olarak saklarsınız!

özet

  • with open(...) as fDosyaları açarken kullanın çünkü dosyayı kendiniz kapatmanıza gerek yoktur ve bazı istisnalar olsa bile dosyayı kapatır.
  • file nesneler yineleme protokolünü destekler, böylece bir dosyayı satır satır okumak kadar basittir for line in the_file_object: .
  • Her zaman kullanılabilir fonksiyonlar / sınıflar için belgelere göz atın. Çoğu zaman görev veya en az bir veya iki iyi görev için mükemmel bir eşleşme vardır. Bu durumda bariz bir seçim olacaktır, readlines()ancak satırları listede saklamadan önce işlemek istiyorsanız, basit bir liste kavraması öneririm.

Son yaklaşım Python'da bir dosya açmak için önerilen yaklaşımdır! Öyleyse neden son? İnsanların büyük çoğunluğu devam etmeden önce bir cevabın ilk birkaç satırına bakmayacak mı?
AMC

@ AMC Cevabı yazdığımda çok fazla düşünmedim. Sence cevabın en üstüne koymalıyım?
MSeifert

En iyisi olabilir, evet. Ayrıca Python 2'den bahsettiğinizi de fark ettim, bu da güncellenebilir.
AMC

Ah soru aslında python-2.x olarak etiketlendi. Daha genel olarak güncellemek mantıklı olabilir. Bir dahaki sefere buna gelip gelmeyeceğimi göreceğim. Önerileriniz için teşekkürler. Çok takdir!
MSeifert

42

Bir Dosyanın Satırlarını Listeye Okumanın Temiz ve Pitonik Yolu


Her şeyden önce, dosyanızı açmaya ve içeriğini verimli ve pitonik bir şekilde okumaya odaklanmalısınız. İşte şahsen tercih ETMEM için bir örnek:

infile = open('my_file.txt', 'r')  # Open the file for reading.

data = infile.read()  # Read the contents of the file.

infile.close()  # Close the file since we're done using it.

Bunun yerine, çok temiz olduğu için hem okuma hem de yazma için aşağıdaki dosyaları açma yöntemini tercih ediyorum ve dosyayı kullandıktan sonra dosyayı kapatmak için fazladan bir adım gerektirmiyor. Aşağıdaki ifadede, dosyayı okumak için açıyoruz ve 'infile' değişkenine ataıyoruz. Bu ifadedeki kodun çalışması tamamlandığında, dosya otomatik olarak kapatılır.

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

Şimdi, bu verileri bir Python Listesine getirmeye odaklanmalıyız çünkü bunlar tekrarlanabilir, verimli ve esnek. Sizin durumunuzda, istenen amaç metin dosyasının her satırını ayrı bir öğeye getirmektir. Bunu yapmak için splitlines () yöntemini aşağıdaki gibi kullanacağız :

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

Nihai Ürün:

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

Kurallarımızı Test Etme:

  • Metin dosyasının içeriği:
     A fost odatã ca-n povesti,
     A fost ca niciodatã,
     Din rude mãri împãrãtesti,
     O prea frumoasã fatã.
  • Test amaçlı ifadeleri yazdırın:
    print my_list  # Print the list.

    # Print each line in the list.
    for line in my_list:
        print line

    # Print the fourth element in this list.
    print my_list[3]
  • Çıktı (unicode karakterler nedeniyle farklı görünümlü):
     ['A fost odat\xc3\xa3 ca-n povesti,', 'A fost ca niciodat\xc3\xa3,',
     'Din rude m\xc3\xa3ri \xc3\xaemp\xc3\xa3r\xc3\xa3testi,', 'O prea
     frumoas\xc3\xa3 fat\xc3\xa3.']

     A fost odatã ca-n povesti, A fost ca niciodatã, Din rude mãri
     împãrãtesti, O prea frumoasã fatã.

     O prea frumoasã fatã.

30

Python 3.4'te pathlibsunulan, aşağıdaki gibi dosyalardan metin okumak için gerçekten uygun bir yöntemi vardır:

from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()

( splitlinesÇağrı, dosyanın tüm içeriğini içeren bir dizeden dosyadaki satır listesine dönüştüren şeydir).

pathlibiçinde çok kullanışlı kolaylıklar var. read_texthoş ve özlüdür ve dosyayı açma ve kapatma konusunda endişelenmenize gerek yoktur. Dosya ile tek yapmanız gereken hepsini tek seferde okumaksa, iyi bir seçimdir.


29

İşte dosyalar üzerinde liste kavrayışlarını kullanarak bir seçenek daha;

lines = [line.rstrip() for line in open('file.txt')]

İşin çoğu Python yorumlayıcısında yapıldığından, bu daha verimli bir yol olmalıdır.


10
rstrip()Potansiyel olarak şeritler her sadece arka boşluk, \n; kullanın .rstrip('\n').
mklement0

Bu ayrıca dosyanın tüm Python uygulamalarında okunduktan sonra kapatılacağını garanti etmez (ana Python uygulaması olan CPython'da olmasına rağmen).
Mark Amery

1
İşin çoğu Python yorumlayıcısında yapıldığından, bu daha verimli bir yol olmalıdır. Bu ne anlama geliyor?
AMC

28
f = open("your_file.txt",'r')
out = f.readlines() # will append in the list out

Şimdi değişken out istediğiniz bir liste (dizi). Bunlardan birini yapabilirsiniz:

for line in out:
    print (line)

Veya:

for line in f:
    print (line)

Aynı sonuçları alacaksınız.


27

Python 2 ve Python 3 ile metin dosyalarını okuma ve yazma; Unicode ile çalışır

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Define data
lines = ['     A first string  ',
         'A Unicode sample: €',
         'German: äöüß']

# Write text file
with open('file.txt', 'w') as fp:
    fp.write('\n'.join(lines))

# Read text file
with open('file.txt', 'r') as fp:
    read_lines = fp.readlines()
    read_lines = [line.rstrip('\n') for line in read_lines]

print(lines == read_lines)

Dikkat edilmesi gerekenler:

  • withsözde içerik yöneticisidir . Açılan dosyanın tekrar kapatılmasını sağlar.
  • Burada beyaz boşluğu soydukları için sadece üreten .strip()veya üretmeyen tüm çözümler ..rstrip()lines

Ortak dosya sonları

.txt

Daha gelişmiş dosya yazma / okuma

Başvurunuz için aşağıdakiler önemli olabilir:

  • Diğer programlama dillerinin desteği
  • Okuma / yazma performansı
  • Kompaktlık (dosya boyutu)

Ayrıca bkz: Veri serileştirme formatlarının karşılaştırılması

Yapılandırma dosyaları oluşturmanın bir yolunu arıyorsanız , Python'daki kısa dosya Yapılandırma dosyalarımı okumak isteyebilirsiniz .


26

Başka bir seçenek, numpy.genfromtxtörneğin:

import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")

Bu, datadosyanızdaki kadar satır içeren bir NumPy dizisi oluşturur.


25

Komut satırından veya stdin'den bir dosya okumak isterseniz, fileinputmodülü de kullanabilirsiniz :

# reader.py
import fileinput

content = []
for line in fileinput.input():
    content.append(line.strip())

fileinput.close()

Dosyaları şu şekilde aktarın:

$ python reader.py textfile.txt 

Daha fazla bilgiyi buradan edinebilirsiniz: http://docs.python.org/2/library/fileinput.html


20

Bunu yapmanın en basit yolu

Basit bir yol:

  1. Tüm dosyayı bir dize olarak okuyun
  2. Dizeyi satır satır bölme

Bir satırda bu şöyle olur:

lines = open('C:/path/file.txt').read().splitlines()

Ancak, içeriğin 2 sürümünü bellekte depolayacağı için bu oldukça verimsiz bir yöntemdir (muhtemelen küçük dosyalar için büyük bir sorun değil, yine de). [Teşekkürler Mark Amery].

2 kolay yol vardır:

  1. Dosyayı yineleyici olarak kullanma
lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]
  1. Python 3.4 veya üstünü kullanıyorsanız pathlib, dosyanız için programınızdaki diğer işlemler için kullanabileceğiniz bir yol oluşturmak üzere daha iyi kullanın :
from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]

Bu kötü bir yaklaşım. Bir kere, aramak .read().splitlines()hiçbir şekilde aramaktan daha basit değildir .readlines(). Bir diğeri için, bellek yetersiz; dosya içeriğinin iki sürümünü (tarafından döndürülen tek dize ve döndürülen dize .read()listesini splitlines()) bir kerede bellekte gereksiz yere saklıyorsunuz .
Mark Amery

@MarkAmery True. Bunu vurguladığınız için teşekkürler. Cevabımı güncelledim.
Jean-Francois T.

14

Sadece splitlines () işlevlerini kullanın. İşte bir örnek.

inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3

Çıktıda satır listesi olacaktır.


Kullanmaya kıyasla bellek yetersiz .readlines(). Bu, dosya içeriğinin iki kopyasını aynı anda belleğe koyar (biri tek bir büyük dize, biri satır listesi olarak).
Mark Amery

11

Eğer bir karşı karşıya istiyorsanız çok büyük / büyük dosyaya istediğiniz hızlı okuma (bir Topcoder / Hackerrank kodlama yarışması olan hayal), bir kerede bir ara belleğe hatlarının oldukça büyük bir yığın okumak yerine olabilir sadece dosya düzeyinde satır satır yineleme.

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)

süreç (çizgi) ne yapar? Ben tanımlanmış böyle bir değişken olmadığı bir hata alıyorum. Sanırım bir şey içe aktarılması gerekiyor ve çoklu işleme ithal etmeye çalıştım.İşlem, ama sanırım bu değil. Lütfen biraz açıklayabilir misiniz? Teşekkürler
Newskooler

1
process(line)verileri işlemek için uygulamanız gereken bir işlevdir. örneğin, bu satır yerine, kullanırsanız print(line), her satırı lines_buffer'dan yazdırır.
Khanal

f.readlines (buffersize) değişmez bir tampon döndürür. doğrudan ara belleğinize okumak istiyorsanız, readinto () işlevini kullanmanız gerekir. Çok daha hızlı olacağım.
David Dehghan

7

Bazı ek avantajlarla bunu yapmanın en kolay yolları:

lines = list(open('filename'))

veya

lines = tuple(open('filename'))

veya

lines = set(open('filename'))

Bu durumda set, hat sırasının korunmadığı ve çoğaltılan hatlardan kurtulmadığımız unutulmamalıdır.

Aşağıda @MarkAmery'den önemli bir ek ekledim :

Eğer demeyeceğiz yana .closedosya nesne üzerinde ne de kullanarak withbazılarında, deyimi Python uygulamaları dosyasını okuma sonra kapalı olsun olmayabilir ve işlem bir açık dosya tanıtıcısı sızdırıyor .

In CPython (normal Python çoğu insan kullanmak uygulanmasının), dosya nesnesi hemen çöp toplama alacak ve bu dosyayı kapatın çünkü bu bir sorun değil, ama yine de genel olarak böyle bir şey yapmak iyi uygulamayı kabul edilir :

with open('filename') as f: lines = list(f) 

hangi Python uygulamasını kullandığınızdan bağımsız olarak dosyanın kapanmasını sağlamak için.


1
Eğer demeyeceğiz yana .closedosya nesne üzerinde ne de kullanarak withbazı Python uygulamalarda, dosyayı deyimi okuma sonra kapalı olsun olmayabilir ve işlem bir açık dosya tanıtıcısı sızdırıyor. CPython (çoğu insan kullanmak normal Python uygulaması), dosya nesne hemen çöp toplama alacak ve bu dosyayı kapatın çünkü bu bir sorun değil, ama yine de genel olarak böyle bir şey yapmak iyi uygulamayı kabul edilir with open('filename') as f: lines = list(f)sağlamak için hangi Python uygulamasını kullanırsanız kullanın dosya kapanır.
Mark Amery

@MarkAmery harika yorumunuz için teşekkür ederiz! Gerçekten onu takdir ederim.
simhumileco

1
@simhumileco Neden en iyi (doğru) çözüm var?
AMC

@AMC çünkü önce, akıl yürütmenin en basit yollarını ve tutarlılığını göstermek istedim.
simhumileco

Ayrıca, umarım cevabım kısa ve okunması kolay olur.
simhumileco

4

Bunu kullan:

import pandas as pd
data = pd.read_csv(filename) # You can also add parameters such as header, sep, etc.
array = data.values

databir veri çerçevesi türüdür ve ndarray almak için değerleri kullanır. Düğmesini kullanarak da bir liste alabilirsiniz array.tolist().


pandas.read_csv()okumak için bir CSV verilerini, nasıl buraya uygun mu?
AMC

4

Anahat ve Özet

A ile filename, dosyayı bir Path(filename)nesneden işlemek veya doğrudan ile open(filename) as faşağıdakilerden birini yapın:

  • list(fileinput.input(filename))
  • kullanma with path.open() as f, çağrıf.readlines()
  • list(f)
  • path.read_text().splitlines()
  • path.read_text().splitlines(keepends=True)
  • yineleme üzerinde fileinput.inputya da fve list.appendher seferinde her bir satır, bir
  • fbağlı bir list.extendyönteme geçmek
  • kullanmak fbir liste anlayışı içinde

Her biri için kullanım durumunu açıklarım.

Python'da bir dosyayı satır satır nasıl okuyabilirim?

Bu mükemmel bir soru. İlk olarak, bazı örnek veriler oluşturalım:

from pathlib import Path
Path('filename').write_text('foo\nbar\nbaz')

Dosya nesneleri tembel yineleyicilerdir, bu yüzden sadece yineleyin.

filename = 'filename'
with open(filename) as f:
    for line in f:
        line # do something with the line

Alternatif olarak, birden fazla dosyanız varsa, fileinput.input , başka bir tembel yineleyici . Sadece bir dosyayla:

import fileinput

for line in fileinput.input(filename): 
    line # process the line

veya birden fazla dosya için bir dosya adı listesi verin:

for line in fileinput.input([filename]*2): 
    line # process the line

Yine fve fileinput.inputher ikisi de tembel yineleyiciler / dönüş. Sadece bir kez bir yineleyici kullanabilirsiniz, bu nedenle ayrıntılardan kaçınırken fonksiyonel kod sağlamak için biraz daha fazlafileinput.input(filename) burada aproposların .

Python'da bir dosyayı satır satır nasıl okuyabilirim listeye ?

Ah ama nedense bir listede mi istiyorsun? Mümkünse bundan kaçınırdım. Eğer ısrar Ama eğer ... sadece sonucunu geçmesi fileinput.input(filename)için list:

list(fileinput.input(filename))

Başka bir doğrudan yanıt, f.readlinesdosyanın içeriğini döndüren (isteğe bağlı hintsayıda karaktere kadar) aramaktır. olabilir birden fazla liste bu şekilde içine bu kadar kırmaya).

Bu dosya nesnesine iki yolla ulaşabilirsiniz. Bunun bir yolu dosya openadını yerleşik olana aktarmaktır :

filename = 'filename'

with open(filename) as f:
    f.readlines()

veya pathlibmodülden yeni Path nesnesini kullanarak (oldukça düşkün oldum ve buradan kullanacağım):

from pathlib import Path

path = Path(filename)

with path.open() as f:
    f.readlines()

list ayrıca dosya yineleyiciyi tüketir ve bir liste döndürür - oldukça doğrudan bir yöntem:

with path.open() as f:
    list(f)

Bölünmeden önce metnin tamamını belleğe tek bir dize olarak okumak sakıncası yoksa, bunu Pathnesne ve splitlines()dize yöntemiyle tek katmanlı olarak yapabilirsiniz . Varsayılan olarak, splitlinesyeni satırları kaldırır:

path.read_text().splitlines()

Yeni satırları saklamak istiyorsanız, şunu iletin keepends=True:

path.read_text().splitlines(keepends=True)

Dosyayı satır satır okumak ve her satırı listenin sonuna eklemek istiyorum.

Son sonucu birkaç yöntemle kolayca gösterdiğimiz göz önüne alındığında, şimdi bu biraz aptalca. Ancak, listenizi oluştururken satırları filtrelemeniz veya işletmeniz gerekebilir, bu nedenle bu isteği mizah edelim.

Kullanmak list.append, eklemeden önce her satıra filtre uygulamanıza veya işlem yapmanıza olanak tanır:

line_list = []
for line in fileinput.input(filename):
    line_list.append(line)

line_list

list.extendÖnceden var olan bir listeniz varsa kullanmak biraz daha doğrudan ve belki de yararlı olacaktır:

line_list = []
line_list.extend(fileinput.input(filename))
line_list

Ya da daha deyimsel olarak, bunun yerine bir liste kavrayışı kullanabilir ve istenirse içinde harita ve filtreleme yapabiliriz:

[line for line in fileinput.input(filename)]

Ya da daha doğrudan, daireyi kapatmak için, doğrudan çizgiler üzerinde çalışmadan yeni bir liste oluşturmak için listeye iletin:

list(fileinput.input(filename))

Sonuç

Bir dosyadan listeye satır almanın birçok yolunu gördünüz, ancak bir listeye büyük miktarda veri sağlamaktan kaçınmanızı ve mümkünse verileri işlemek için Python'un tembel yinelemesini kullanmanızı öneriyorum.

Yani, tercih fileinput.inputveya with path.open() as f.


4

Belgede boş satırlar olması durumunda, içeriği okumak ve iletmek istiyorum filter boş dize öğelerini önlemek için

with open(myFile, "r") as f:
    excludeFileContent = list(filter(None, f.read().splitlines()))

1
Bu kuralsız, dikkatli olun.
AMC

3

NumPy'de loadtxt komutunu da kullanabilirsiniz. Bu genfromtxt'den daha az durumu kontrol eder, bu nedenle daha hızlı olabilir.

import numpy
data = numpy.loadtxt(filename, delimiter="\n")

2

Aşağıdakileri kullanmayı seviyorum. Çizgileri hemen okuma.

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

Veya liste kavrayışı kullanarak:

contents = [line.strip() for line in open(filepath, 'r').readlines()]

2
İçin gerek yoktur readlines(), hatta bir hafıza düşüklüğüne maruz kalmaz. Bir (metin) dosyası üzerinden yineleme her satırı sırayla verdiğinden onu kaldırabilirsiniz.
Eric O Lebigot

2
Dosyayı withaçmak (ve dolaylı olarak kapatmak) için bir ifade kullanmalısınız .
Aran-Fey

2

Aşağıdaki yöntemlerden birini denemek istiyorum. Kullandığım örnek dosyanın adı var dummy.txt. Dosyayı burada bulabilirsiniz . Dosya kod ile aynı dizinde olduğunu varsayalım ( fpathuygun dosya adı ve klasör yolunu içerecek şekilde değiştirebilirsiniz ).

Aşağıdaki örneklerin her ikisinde de, istediğiniz liste verilmiştir lst.

1.> İlk yöntem :

fpath = 'dummy.txt'
with open(fpath, "r") as f: lst = [line.rstrip('\n \t') for line in f]

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2.> de ikinci yöntem , tek bir kullanabilir csv.reader Python Standart kütüphane modülün :

import csv
fpath = 'dummy.txt'
with open(fpath) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter='   ')
    lst = [row[0] for row in csv_reader] 

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

İki yöntemden birini kullanabilirsiniz. lstİki yöntemde yaratılma süresi neredeyse eşittir.


1
İkinci yaklaşımın avantajı nedir? Neden kenar vakaları (sınırlayıcı ve tırnak işaretleri) ekleyen ek bir kütüphane çağırmalısınız?
Charlie Harding

delimiter=' 'Argüman ne için?
AMC

2

İşte dosya G / Ç basitleştirmek için kullandığım bir Python (3) yardımcı kütüphane sınıfı:

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

Daha sonra FileIO.linesişlevi şu şekilde kullanırsınız:

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

Unutmayın mode( "r"varsayılan olarak) ve filter_fnparametrelere (varsayılan olarak boş hatlar için çekler) isteğe bağlıdır.

Hatta kaldırabilir read, writeve deleteyöntem ve sadece bırakın FileIO.lines, hatta adında ayrı bir yöntem haline çevirmek read_lines.


Bu yardımcının varlığını haklı çıkarmaktan lines = FileIO.lines(path)gerçekten daha mı basit with open(path) as f: lines = f.readlines()? Arama başına 17 karakter tasarruf edersiniz. (Ve çoğu zaman, performans ve bellek nedenleriyle, satırlarını zaten bir listeye okumak yerine doğrudan bir dosya nesnesi üzerinde döngü yapmak isteyeceksiniz, bu yüzden bunu sık sık kullanmak istemeyeceksiniz!) genellikle küçük yarar fonksiyonları yaratmanın bir hayranı, ama bu bana gereksiz gibi standart kitaplık bize zaten kısa ve kolay bir şey yazmak için yeni bir yol yaratmak gibi hissediyorum.
Mark Amery

@MarkAmery'nin söylediklerine ek olarak, bunun için neden bir sınıf kullanıyorsunuz?
AMC

1

Komut satırı sürümü

#!/bin/python3
import os
import sys
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
filename = dname + sys.argv[1]
arr = open(filename).read().split("\n") 
print(arr)

Şununla çalıştır:

python3 somefile.py input_file_name.txt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.