python

2012-06-07 34 views
6

ters sırada bir csv dosyasını nasıl okuyacağımı .txt dosyası için nasıl yapılacağını biliyorum ... ama şimdi bir .csv dosyası için bazı sıkıntılar alıyorum. Python'da alttan bir csv dosyasını nasıl okuyabilirim? Bir metin dosyası gibipython

+3

[Şu ana kadar denedim ne?] (Http://mattgemmell.com/2008/12/08/what-have-you-tried/) – JoeFish

+2

Eğer linux üzerinde? Dosyayı 'tac' o zaman oku. – dm03514

+0

Bize bir '.txt' dosyası için neyin var olduğunu göster.Şanslar aynı tekniği kullanabilmenizdir. – NPE

cevap

19

Hemen hemen aynı şekilde: bir liste halinde her şeyi okumak ve sonra geriye gidin: Eğer fantezi almak istiyorsanız, size okur bir sürü kod yazabilirsiniz

import csv 
with open('test.csv', 'r') as textfile: 
    for row in reversed(list(csv.reader(textfile))): 
     print ', '.join(row) 

Dosyanın sonunda başlayan ve geriye doğru çalışan, bir satırda bir satır yayan ve daha sonra csv.reader'a besleyen bloklar, ancak yalnızca aranabilir bir dosyayla, yani disk dosyaları ile değil, standart girişle çalışacaktır.


Kimimiz belleğe sığmayan dosyaları var, herkes bellekte dosyanın tamamını depolamak gerektirmeyen bir çözüm ile gelebilir?

Bu biraz zorlayıcı. Neyse ki, tüm csv.reader, next() numaralı telefona çağrı başına bir dize (satır) döndüren yineleyici benzeri bir nesnedir. Bu yüzden bütün dosyasında çekmeye gerek kalmadan, Darius Bacon geriye bir dosyanın satırları okumak için "Most efficient way to search the last x lines of a file in python" sunulan tekniği kapmak:

import os 

def reversed_lines(file): 
    "Generate the lines of file in reverse order." 
    part = '' 
    for block in reversed_blocks(file): 
     for c in reversed(block): 
      if c == '\n' and part: 
       yield part[::-1] 
       part = '' 
      part += c 
    if part: yield part[::-1] 

def reversed_blocks(file, blocksize=4096): 
    "Generate blocks of file's contents in reverse order." 
    file.seek(0, os.SEEK_END) 
    here = file.tell() 
    while 0 < here: 
     delta = min(blocksize, here) 
     here -= delta 
     file.seek(here, os.SEEK_SET) 
     yield file.read(delta) 

ve çizgileri ters koduna reversed_lines beslemek önce onlar reversed ve list ihtiyacını ortadan kaldırarak, csv.reader olsun:

import csv 
with open('test.csv', 'r') as textfile: 
    for row in csv.reader(reversed_lines(textfile)): 
     print ', '.join(row) 

(bellekte ipucu bloğunun bir karakter bazında karakteri ters gerektirmez mümkün bir daha Pythonictir çözüm vardır: sadece almak ark blokta satır sonu bulunan dizinleri tersine çevir ve bloğu dilimlemek için kullanın) ve satır kümelerini birbiri ardına gelen bloklardan birbirine yapıştırmak için chain'u chain kullanır, ancak bu okuyucu için bir egzersiz olarak kalır.


CSV dosyasındaki sütunlar yeni satır ihtiva etmemesi yukarıdaki reversed_lines() deyim yalnızca çalıştığını belirtmek gerekir.

Aargh! Her zaman bir şey vardır. Neyse ki, bu sorunu çözmek için çok kötü değil: Elbette

def reversed_lines(file): 
    "Generate the lines of file in reverse order." 
    part = '' 
    quoting = False 
    for block in reversed_blocks(file): 
     for c in reversed(block): 
      if c == '"': 
       quoting = not quoting 
      elif c == '\n' and part and not quoting: 
       yield part[::-1] 
       part = '' 
      part += c 
    if part: yield part[::-1] 

CSV lehçesi " kullanmıyorsa tırnak karakteri değiştirmek gerekir. @ Mike-desimone 'nin yanıtı üzerine bina

+0

aynı mı? f = open (FilePath, "rb") csvfile = tersine çevrilmiş ([satır satırı csv.reader (f)]) – SirC

+0

Dosyalarınızı kapatmak için çöp toplamaya güvenmemelisiniz. Bu, çöp toplama için referans sayımı kullanmayan Python uygulamasında çok işe yaramaz ve aynı zamanda CPython 3.2'de ResourceWarning işlevini tetikler (etkinleştirilmişse). –

+1

Başka bir açıklama: [Okuyucudaki çizgi için] 'deyimden hoşlanmıyorum ve' listeyi (okuyucu) tercih ederim, ki bu noktaya daha çok şey geliyor. –

0

.

import os 

class ReversedFile(object): 
    def __init__(self, f, mode='r'): 
     """ 
     Wraps a file object with methods that make it be read in reverse line-by-line 

     if ``f`` is a filename opens a new file object 

     """ 
     if mode != 'r': 
      raise ValueError("ReversedFile only supports read mode (mode='r')") 

     if not type(f) == file: 
      # likely a filename 
      f = open(f) 

     self.file = f 
     self.lines = self._reversed_lines() 

    def _reversed_lines(self): 
     "Generate the lines of file in reverse order." 
     part = '' 
     for block in self._reversed_blocks(): 
      for c in reversed(block): 
       if c == '\n' and part: 
        yield part[::-1] 
        part = '' 
       part += c 
     if part: yield part[::-1] 

    def _reversed_blocks(self, blocksize=4096): 
     "Generate blocks of file's contents in reverse order." 
     file = self.file 

     file.seek(0, os.SEEK_END) 
     here = file.tell() 
     while 0 < here: 
      delta = min(blocksize, here) 
      here -= delta 
      file.seek(here, os.SEEK_SET) 
      yield file.read(delta) 


    def __getattribute__(self, name): 
     """ 
     Allows for the underlying file attributes to come through 

     """ 
     try: 
      # ReversedFile attribute 
      return super(ReversedFile, self).__getattribute__(name) 
     except AttributeError: 
      # self.file attribute 
      return getattr(self.file, name) 

    def __iter__(self): 
     """ 
     Creates iterator 

     """ 
     return self 

    def seek(self): 
     raise NotImplementedError('ReversedFile does not support seek') 

    def next(self): 
     """ 
     Next item in the sequence 

     """ 
     return self.lines.next() 

    def read(self): 
     """ 
     Returns the entire contents of the file reversed line by line 

     """ 
     contents = '' 

     for line in self: 
      contents += line 

     return contents 

    def readline(self): 
     """ 
     Returns the next line from the bottom 

     """ 
     return self.next() 

    def readlines(self): 
     """ 
     Returns all remaining lines from the bottom of the file in reverse 

     """ 
     return [x for x in self] 
0

Git bunun için: Burada bir piton dosya nesnesi olarak aynı yapıya sağlar ama çizgi ile ters, çizgi okunan bir çözümdür. Bu, bir CSV dosyasındaki satırları tersine çevirmek için basit bir programdır.

import csv 
BC_file = open('Master.csv', 'rb') 
BC_reader = csv.reader(BC_file) 
next(BC_reader) 
for row in reversed(list(BC_reader)): 
    print row[0]