Python - write () ve writelines () ve birleştirilmiş dizeler


124

Bu yüzden Python öğreniyorum. Derslerden geçiyorum ve her kullanıcı giriş değişkeni arasında (nesnesi ) varken, çok fazla sayıda kişiyi target.write()tek olarak yoğunlaştırmam gereken bir problemle karşılaştım .write()"\n"write()

Ben geldim:

nl = "\n"
lines = line1, nl, line2, nl, line3, nl
textdoc.writelines(lines)

Yapmaya çalışırsam:

textdoc.write(lines)

Bir hata alıyorum. Ama yazarsam:

textdoc.write(line1 + "\n" + line2 + ....)

O zaman iyi çalışıyor. Satırsonu için neden bir dizge kullanamıyorum write()ama içinde kullanabilirim writelines()?

Python 2.7 Google'da arama yaptığımda bulduğum kaynakların çoğu kafamın çok üzerindeydi, ben hala sıradan bir insanım.


linesörneğinizde bir dize değil. Altı dizeden oluşan bir demettir.
Bachsau

Yanıtlar:


147
  • writelines yinelenebilir dizeler bekler
  • write tek bir dizge bekler.

line1 + "\n" + line2bu dizeleri, iletmeden önce tek bir dizede birleştirir write.

Çok sayıda hattınız varsa kullanmak isteyebileceğinizi unutmayın "\n".join(list_of_lines).


50
Daha spesifik olarak, writelinesyinelenebilir. Bir liste, demet veya oluşturucu kullanabilirsiniz.
Mark Ransom

Cevabınız için teşekkürler efendim. İsme göre (list_of_lines) dizelerin bir listesini yapmam ve sonra .join (list) 'e geçmem gerektiğini varsayıyorum.
AbeLinkon

9
Çok satırınız varsa neden writeyerine kullanmalısınız writelines? Yazılılar, geçici birleştirilmiş bir dize oluşturmak zorunda olmadığından, sadece satırlar üzerinde yineleyerek daha iyi performans gösterebilir.
Bouke


1
Tek bir dize ayrıca Python'da
yinelenebilir

123

Neden write () 'da bir satırsonu için dizge kullanamıyorum ama onu writelines () içinde kullanabilirim?

Fikir şudur: Tek bir dizge yazmak istiyorsanız bunu ile yapabilirsiniz write(). Bir dizi dizeniz varsa, hepsini kullanarak yazabilirsiniz writelines().

write(arg)bir dizeyi bağımsız değişken olarak bekler ve bunu dosyaya yazar. Bir dizge listesi sağlarsanız, bu bir istisna oluşturur (bu arada, bize hataları gösterin!).

writelines(arg)argüman olarak yinelenebilir olmasını bekler (yinelenebilir bir nesne, en genel anlamda bir tuple, bir liste, bir dizge veya bir yineleyici olabilir). Yineleyicide bulunan her öğenin bir dizge olması beklenir. Sağladığınız bir dizi dizedir, bu nedenle işler yolunda gitti.

Dizelerin (dizelerin) doğası her iki işlev için de önemli değildir, yani sadece onlara ne sağlarsanız onu dosyaya yazarlar. İlginç writelines()olan, kendi başına satırsonu karakterleri eklememesidir, bu nedenle yöntem adı aslında oldukça kafa karıştırıcı olabilir. Aslında adı verilen hayali bir yöntem gibi davranır write_all_of_these_strings(sequence).

Aşağıdakiler, Python'da her dizeyi kendi satırında tutarken bir dosyaya dize listesi yazmanın deyimsel bir yoludur:

lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
    f.write('\n'.join(lines))

Bu, dosyayı sizin için kapatmanızı sağlar. Yapı '\n'.join(lines), listedeki dizeleri birleştirir (bağlar) ve linesyapıştırıcı olarak '\ n' karakterini kullanır. +Operatörü kullanmaktan daha verimlidir .

Aynı linesdiziden başlayarak, aynı çıktıyla biten ancak şunu kullanarak writelines():

lines = ['line1', 'line2']
with open('filename.txt', 'w') as f:
    f.writelines("%s\n" % l for l in lines)

Bu, bir üreteç ifadesini kullanır ve dinamik olarak satırsonu ile sonlandırılmış dizeler oluşturur. writelines()bu dizgi dizisini yineler ve her öğeyi yazar.

Düzenleme: Dikkat etmeniz gereken başka bir nokta:

write()ve tanıtılmadan readlines()önce writelines()vardı. writelines()daha sonra bir muadili olarak tanıtıldı readlines(), böylece sadece okunan dosya içeriğini kolayca yazabilirsin readlines():

outfile.writelines(infile.readlines())

Gerçekten, bu kadar writelineskafa karıştırıcı bir isme sahip olmasının ana nedeni budur . Ayrıca bugün bu yöntemi artık gerçekten kullanmak istemiyoruz. verileri yazmaya readlines()başlamadan önce tüm dosyayı makinenizin belleğine okur writelines(). Her şeyden önce bu zaman kaybedebilir. Diğer bölümleri okurken neden verilerin bazı kısımlarını yazmaya başlamıyorsunuz? Ancak en önemlisi, bu yaklaşım çok fazla bellek tüketebilir. Giriş dosyasının makinenizin belleğinden daha büyük olduğu uç bir senaryoda, bu yaklaşım işe yaramayacaktır bile. Bu sorunun çözümü yalnızca yineleyiciler kullanmaktır. Çalışan bir örnek:

with open('inputfile') as infile:
    with open('outputfile') as outfile:
        for line in infile:
            outfile.write(line)

Bu, girdi dosyasını satır satır okur. Bir satır okunduğu anda bu satır çıktı dosyasına yazılır. Şematik olarak konuşulduğunda, bellekte her zaman tek bir satır vardır (okuma satırları / yazma yaklaşımı durumunda tüm dosya içeriğinin bellekte olmasıyla karşılaştırıldığında).


5
@AbeLinkon: Bu sonucu desteklemem. write()ve writelines()temelde eşdeğerdir ve kullanımları da kişisel bir zevk meselesidir. Bununla birlikte, son derece uzun bir dizge listesi (adı verilen lines) için yazmanın f.write('\n'.join(lines))daha az verimli olduğuna dikkat etmek önemlidir for l in line: f.write('%s\n' % l). İlk durumda, yazmadan önce bellekte tamamen yeni ve çok uzun bir dizgi oluşturulur. İkinci durumda, veriler parça parça yazılır.
Dr Jan-Philip Gehrcke

3
f.write ('\ n'.join (lines)) çalıştırdığımda son nl'yi eklemedi.
Jiminion

5
Tabii ki yapmazsın, outf.writelines(inf.readlines())daha doğrusu outf.writelines(inf). Artık kullanmak istemediğimiz işlev readlines()değil writelines().
moooeeeep

2
@moooeeeep: işlevinde / uygulamasında hiçbir şey yanlış olmasa writelines()da, açıklandığı gibi anlambilimi idealden daha azdır. Bu yüzden hiç kullanmadım. Ve asla kaçırmadım.
Dr Jan-Philip Gehrcke

2
@AbeLinkon - belki de bu cevabı kabul etmeyi düşünmelisiniz, başlangıçta kabul ettiğinizden açıkça daha iyidir
Peter M. - Monica'nın kısaltması

-4

sadece bir listeyi kaydetmek ve yüklemek istiyorsanız Pickle'ı deneyin

Turşu tasarrufu:

with open("yourFile","wb")as file:
 pickle.dump(YourList,file)

ve yükleniyor:

with open("yourFile","rb")as file:
 YourList=pickle.load(file)

-5

Aslında, bence problem değişken "çizgilerinizin" kötü olmasıdır. Satırları bir demet olarak tanımladınız, ancak write () 'ın bir dizge gerektirdiğine inanıyorum. Değiştirmeniz gereken tek şey virgüllerinizi artılara (+) dönüştürmek.

nl = "\n"
lines = line1+nl+line2+nl+line3+nl
textdoc.writelines(lines)

çalışmalı.


-5

Zed Shaw'un kitabından 16. Alıştırma? Kaçış karakterlerini aşağıdaki gibi kullanabilirsiniz:

paragraph1 = "%s \n %s \n %s \n" % (line1, line2, line3)
target.write(paragraph1)
target.close()

Çok zayıf çözüm. Bu şekilde birkaç satır bitiştirmek istiyorsa, bunu böyle yapmalıdır: " \n ".join((line1, line2, line3)).
Bachsau
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.