Python kullanarak bir csv dosyasını düzenlerken üstbilgileri atla


209

Python kullanarak bir csv düzenlemek için aşağıda belirtilen kodu kullanıyorum. Kodda çağrılan işlevler kodun üst kısmını oluşturur.

Sorun: Ben aşağıda belirtilen kod csv 2. satırdan düzenlemeye başlamak istiyorum, ben başlıklarını içeren 1. satır hariç tutmak istiyorum. Şu anda sadece 1. sıradaki fonksiyonları uyguluyor ve başlık satırım değişiyor.

in_file = open("tmob_notcleaned.csv", "rb")
reader = csv.reader(in_file)
out_file = open("tmob_cleaned.csv", "wb")
writer = csv.writer(out_file)
row = 1
for row in reader:
    row[13] = handle_color(row[10])[1].replace(" - ","").strip()
    row[10] = handle_color(row[10])[0].replace("-","").replace("(","").replace(")","").strip()
    row[14] = handle_gb(row[10])[1].replace("-","").replace(" ","").replace("GB","").strip()
    row[10] = handle_gb(row[10])[0].strip()
    row[9] = handle_oem(row[10])[1].replace("Blackberry","RIM").replace("TMobile","T-Mobile").strip()
    row[15] = handle_addon(row[10])[1].strip()
    row[10] = handle_addon(row[10])[0].replace(" by","").replace("FREE","").strip()
    writer.writerow(row)
in_file.close()    
out_file.close()

rowDeğişkeni başlatarak bu sorunu çözmeye çalıştım 1ama işe yaramadı.

Lütfen bu sorunu çözmeme yardımcı olun.


Yanıtlar:


370

Kişisel readerdeğişken bir iterable, üzerinde döngü tarafından satırları almak olduğunu.

Döngünüzden önce bir öğeyi atlamasını sağlamak için next(reader, None), dönüş değerini arayın ve yok sayın.

Ayrıca kodunuzu biraz basitleştirebilirsiniz; otomatik olarak kapatılması için açılan dosyaları içerik yöneticisi olarak kullanın:

with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
   reader = csv.reader(infile)
   next(reader, None)  # skip the headers
   writer = csv.writer(outfile)
   for row in reader:
       # process each row
       writer.writerow(row)

# no need to close, the files are closed automatically when you get to this point.

Eğer çok kolay işlenmemiş çıktı dosyasına başlığını yazmak isteseydim, çıktısını geçmesi next()için writer.writerow():

headers = next(reader, None)  # returns the headers or `None` if the input is empty
if headers:
    writer.writerow(headers)

22
Bir alternatif de kullanmaktır for row in islice(reader, 1, None)- nexten basit "bir satırı atla" işlerinden daha az açık olsa da , birden fazla başlık satırı atlamak (veya sadece belirli parçaları almak vb.) İçin oldukça kullanışlıdır
Jon Clements

Kullanmayı düşünürdümtry: writer.write(next(reader))... except StopIteration: # handle empty reader
Jon Clements

@JonClements: Belki. Bu işlem yaklaşık öğretmek gerek kalmadan yeterince iyi çalışıyor try:/ ' except:.
Martijn Pieters

1
@JonClements: Açık nextyinelemenin avantajı "ücretsiz" olmasıdır; her yinelemeye sonsuza kadar ekleyerek (kuşkusuz çok az miktarda) ek yükü islicesarar reader. consumeDan tarifiitertools nerede durumunda, müteakip kullanımına sarma eklemeden, hızla birçok değerleri atlamak için kullanılabilecek islicebir olurdu startama hiçbir endhavai bir şey kazanıyor değildir bu yüzden.
ShadowRanger

120

Bunu çözmenin başka bir yolu da başlık satırını "atlayan" ve DizinAdı sınıfını kullanmaktır.

Aşağıdaki gibi "foo.csv" verilir:

FirstColumn,SecondColumn
asdf,1234
qwer,5678

DictReader'ı şu şekilde kullanın:

import csv
with open('foo.csv') as f:
    reader = csv.DictReader(f, delimiter=',')
    for row in reader:
        print(row['FirstColumn'])  # Access by column header instead of column number
        print(row['SecondColumn'])

21
Sorunun XY sorununun bir örneği gibi göründüğünden, bunun gerçek cevap olduğunu hissediyorum .
MariusSiuram

3
DictReader kesinlikle gitmek için bir yoldur
Javier Arias

4
Bunun yalnızca DictReader'ı oluştururken alan adları parametresini atlarsanız işe yaradığını unutmayın. Belgelere göre: If the fieldnames parameter is omitted, the values in the first row of the file f will be used as the fieldnames.Bkz. Docs.python.org/2/library/csv.html
BuvinJ

7

Yapmak row=1hiçbir şeyi değiştirmeyecektir, çünkü döngü sonuçlarının üzerine yazacaksınız.

next(reader)Bir satırı atlamak istiyorsunuz .


Bunu değiştirmeyi denedim for row in next(reader):ama bana IndexError: string index out of rangehata veriyor

For döngüsünden önce kullanın: next(reader); for row in reader:....
dlazesz
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.