Python ile bir listeye veya diziye bir metin dosyası nasıl okunur


176

Bir liste veya dizi python içine bir metin dosyasının satırlarını okumaya çalışıyorum. Sadece oluşturulduktan sonra liste veya dizideki herhangi bir öğeye tek tek erişebilmeliyim.

Metin dosyası aşağıdaki gibi biçimlendirilir:

0,0,200,0,53,1,0,255,...,0.

...Yukarıda olduğu yerde, gerçek metin dosyasında yüzlerce veya binlerce öğe vardır.

Dosyayı bir listeye okumaya çalışmak için aşağıdaki kodu kullanıyorum:

text_file = open("filename.dat", "r")
lines = text_file.readlines()
print lines
print len(lines)
text_file.close()

Aldığım çıktı:

['0,0,200,0,53,1,0,255,...,0.']
1

Görünüşe göre tüm dosyayı tek tek öğelerden ziyade tek bir öğenin listesine okuyor. Neyi yanlış yapıyorum?


1
Bir not gibi. Bu soru, bir csv dosyasının Python'daki bir listeye nasıl okunacağı gibi yeniden ifade edilmesi gerektiği gibi görünüyor. Ama OP'nin 4 yıl önce bilmediğim orijinal niyetlerini erteliyorum.
demongolem



1
Aslında, en iyi cevaba bakıldığında, bu stackoverflow.com/questions/3277503/… ' nin bir kopyasıdır .
AMC

Yanıtlar:


135

Kullanarak dizenizi bir değerler listesine bölmeniz gerekecek split()

Yani,

lines = text_file.read().split(',')

1
Sana satırlı düşünün Bu cevap ... Daha iyisini olabileceğini düşünüyorum .csv(OP tarafından belirtildiği gibi) dosyası, örneğin üst üste tarafından alfabetik karakterler 3 içeren bir dosya ( a,b,c, d,e,f, vs) ve ne olsun yukarıda açıklanan prosedür uygulamak şöyle bir listedir: ['a', 'b', 'c\nd', 'e', ... ](öğeyi not edin 'c\nd'). Yukarıdaki soruna dikkat etmeden, bu prosedürün tek bir mega listede tek tek satırlardaki verileri daralttığını eklemek istiyorum, genellikle kayıt odaklı bir veri dosyası işlerken istediğim şey değil.
gboffi

split yeni satırlardan ayrılacak. Bunu yapmayın, csvmodül veya başka bir mevcut ayrıştırıcı kullanın
Jean-François Fabre

43

Gibi numpy loadtxt kullanabilirsiniz

from numpy import loadtxt
lines = loadtxt("filename.dat", comments="#", delimiter=",", unpack=False)

1
Buna da ihtiyacım var. Raspberry Pi'de numpy'nin çok yavaş çalıştığını fark ettim. Bu uygulama için bir dosyayı açmak ve satır satır okumak için geri döndüm.
Guus

2
Bu, dtype : data-typeparametre aracılığıyla da biçim belirtmek için kullanışlıdır . docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html Pandalar read_csv'nin kullanımı çok kolaydır. Ancak bunun için biçim belirtmenin bir yolunu görmedim. Dosyamdan şamandıralar okurken dizeye ihtiyacım vardı. Loadtxt gösterdiğiniz için @Thiru teşekkürler.
Özgür Öztürk

1
txt dosyaları dize içeriyorsa, dtype belirtilmelidir, bu nedenle lines = loadtxt ("dosyaadı.dat", dtype = str, comments = "#", ayırıcı = ",", unpack = False)
Alex M981 gibi olmalıdır

19

Yani bir liste listesi oluşturmak istiyorsunuz ... Boş bir listeyle başlamamız gerekiyor

list_of_lists = []

daha sonra, dosya içeriğini satır satır okuyoruz

with open('data') as f:
    for line in f:
        inner_list = [elt.strip() for elt in line.split(',')]
        # in alternative, if you need to use the file content as numbers
        # inner_list = [int(elt.strip()) for elt in line.split(',')]
        list_of_lists.append(inner_list)

Yaygın bir kullanım durumu sütunsal verilerdir, ancak depolama birimlerimiz tek tek okuduğumuz dosya satırlarıdır, bu nedenle liste listenizi aktarmak isteyebilirsiniz . Bu, aşağıdaki deyimle yapılabilir

by_cols = zip(*list_of_lists)

Diğer bir yaygın kullanım, her sütuna bir ad vermektir

col_names = ('apples sold', 'pears sold', 'apples revenue', 'pears revenue')
by_names = {}
for i, col_name in enumerate(col_names):
    by_names[col_name] = by_cols[i]

homojen veri öğeleri üzerinde çalışabilmeniz için

 mean_apple_prices = [money/fruits for money, fruits in
                     zip(by_names['apples revenue'], by_names['apples_sold'])]

Yazdıklarımın çoğu csvstandart kütüphaneden modül kullanılarak hızlandırılabilir . Başka bir üçüncü taraf modülü, pandastipik bir veri analizinin birçok yönünü otomatikleştirmenizi sağlar (ancak bir dizi bağımlılığa sahiptir).


Güncelleme Python 2'de zip(*list_of_lists)farklı (aktarılmış) bir liste listesi dönerken, Python 3'te durum değişti ve abone edilemeyen bir zip nesnesizip(*list_of_lists) döndürür .

Eğer varsa gerek endeksli erişimini kullanabilirsiniz

by_cols = list(zip(*list_of_lists))

size Python'un her iki sürümünde de bir liste verir.

Öte yandan, dizinli erişime ihtiyacınız yoksa ve istediğiniz şey sadece sütun adlarıyla dizinlenmiş bir sözlük oluşturmaksa, bir zip nesnesi gayet iyi ...

file = open('some_data.csv')
names = get_names(next(file))
columns = zip(*((x.strip() for x in line.split(',')) for line in file)))
d = {}
for name, column in zip(names, columns): d[name] = column

OP, bir "liste listesi" değil, bir CSV'den veri listesi istediklerini söyledi. Sadece csvmodülü kullanın ...
Blairg23

4

Bu soru, bir dosyadan virgülle ayrılmış değer içeriğinin tekrarlanabilir bir listeye nasıl okunacağını soruyor:

0,0,200,0,53,1,0,255,...,0.

Bunu yapmanın en kolay yolu csvaşağıdaki modüldür:

import csv
with open('filename.dat', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',')

Şimdi, bu şekilde kolayca tekrarlayabilirsiniz spamreader:

for row in spamreader:
    print(', '.join(row))

Daha fazla örnek için belgelere bakın .

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.