अजगर में एक फ़ाइल की पहली एन लाइनें पढ़ें


150

हमारे पास एक बड़ा कच्चा डेटा फ़ाइल है जिसे हम एक निर्दिष्ट आकार में ट्रिम करना चाहते हैं। मैं .net c # में अनुभवी हूं, लेकिन चीजों को सरल बनाने और रुचि से बाहर करने के लिए यह अजगर में करना चाहूंगा।

मैं अजगर में एक पाठ फ़ाइल की पहली एन लाइनें प्राप्त करने के बारे में कैसे जाऊँगा? क्या उपयोग किए जा रहे OS का कार्यान्वयन पर कोई प्रभाव पड़ेगा?


क्या मैं कमांड लाइन तर्क के रूप में n दे सकता हूं
नॉनस जूल

जवाबों:


240

अजगर २

with open("datafile") as myfile:
    head = [next(myfile) for x in xrange(N)]
print head

अजगर ३

with open("datafile") as myfile:
    head = [next(myfile) for x in range(N)]
print(head)

यहाँ एक और तरीका है (दोनों पायथन 2 और 3)

from itertools import islice
with open("datafile") as myfile:
    head = list(islice(myfile, N))
print head

1
धन्यवाद, यह वास्तव में बहुत उपयोगी है। दोनों के बीच क्या अंतर है? (प्रदर्शन, आवश्यक पुस्तकालयों, संगतता आदि के संदर्भ में)?
रसेल

1
मैं प्रदर्शन के समान होने की उम्मीद करता हूं, शायद पहले थोड़ा तेज हो। लेकिन अगर फ़ाइल में कम से कम N लाइन्स नहीं हैं तो पहला काम नहीं करेगा। आपके द्वारा उपयोग किए जा रहे कुछ विशिष्ट डेटा के विरुद्ध प्रदर्शन को मापने के लिए आप सर्वश्रेष्ठ हैं।
जॉन ला रोय

1
पायथन 2.6 पर बयान के साथ काम करता है, और 2.5 पर अतिरिक्त आयात विवरण की आवश्यकता होती है। 2.4 या उससे पहले के लिए, आपको एक प्रयास के साथ कोड को फिर से लिखना होगा ... ब्लॉक को छोड़कर। स्थिर रूप से, मैं पहला विकल्प पसंद करता हूं, हालांकि जैसा कि उल्लेख किया गया है कि छोटी फाइलों के लिए दूसरा अधिक मजबूत है।
Alasdair

1
islice शायद तेज है क्योंकि इसे C. में लागू किया गया है
ऐलिस पर्ससेल

22
ध्यान रखें कि यदि फ़ाइलें कम हैं, तो N लाइनें यह StopIteration अपवाद को बढ़ाएंगी जिसे आपको संभालना होगा
Ilian Iliev

19
N = 10
with open("file.txt", "a") as file:  # the a opens it in append mode
    for i in range(N):
        line = next(file).strip()
        print(line)

23
जब भी मैं f = open("file")फ़ाइल को बंद करने के लिए बिना किसी अपवाद के हैंडल करता हूं, तो मैं cringe फ़ाइलों को संभालने के लिए पायथोनिक तरीका एक संदर्भ प्रबंधक के साथ है, अर्थात बयान के साथ उपयोग करना। यह इनपुट आउटपुट पायथन ट्यूटोरियल में कवर किया गया है । "It is good practice to use the with keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way."
मार्क मिकोफ्की

1
फाइल को एपेंड मोड में क्यों खोलें?
एएमसी

13

यदि आप पहली पंक्तियों को जल्दी से पढ़ना चाहते हैं और आपको प्रदर्शन की परवाह नहीं है तो आप .readlines()सूची ऑब्जेक्ट का उपयोग कर सकते हैं और फिर सूची को स्लाइस कर सकते हैं ।

पहले 5 लाइनों के लिए जैसे:

with open("pathofmyfileandfileandname") as myfile:
    firstNlines=myfile.readlines()[0:5] #put here the interval you want

नोट: पूरी फ़ाइल पढ़ी जाती है इसलिए प्रदर्शन के दृष्टिकोण से सर्वश्रेष्ठ नहीं है, लेकिन इसका उपयोग करना आसान है, लिखने के लिए तेज़ और याद रखने में आसान है, इसलिए यदि आप चाहते हैं कि केवल एक बार की गई गणना बहुत सुविधाजनक हो

print firstNlines

अन्य उत्तरों की तुलना में एक लाभ यह है कि आसानी से लाइनों की सीमा का चयन करने की संभावना है जैसे कि पहले 10 लाइनों [10:30]को छोड़ना [:-10]या 10 तक रहता है या केवल लाइनों को लेना [::2]


2
शीर्ष उत्तर संभवतः अधिक कुशल है, लेकिन यह छोटी फ़ाइलों के लिए एक आकर्षण की तरह काम करता है।
T.Cmemelevskij 12

2
ध्यान दें कि यह वास्तव में पूरी फाइल को पहले एक सूची (myfile.readlines ()) में पढ़ता है और फिर इसकी पहली 5 पंक्तियों को हटा देता है।
अब्देअल्जीके

2
इससे बचना चाहिए।
अनिलबाई

1
मैं इसका उपयोग करने का कोई कारण नहीं देखता, यह बहुत अधिक कुशल समाधानों की तुलना में कोई सरल नहीं है।
एएमसी

@AMC फ़ीडबैक के लिए धन्यवाद, मैं डेटा को एक्सप्लोर करने के लिए कंसोल में इसका उपयोग करता हूं जब मुझे पहली पंक्तियों के लिए त्वरित रूप से देखना पड़ता है, तो इससे मुझे कोड लिखने में समय की बचत होती है।
जीएम

9

मैं जो कर रहा हूं वह एन लाइनों का उपयोग करके कॉल करना है pandas। मुझे लगता है कि प्रदर्शन सबसे अच्छा नहीं है, लेकिन उदाहरण के लिए यदि N=1000:

import pandas as pd
yourfile = pd.read('path/to/your/file.csv',nrows=1000)

3
nrowsविकल्प का उपयोग करना बेहतर होगा , जिसे 1000 पर सेट किया जा सकता है और पूरी फाइल लोड नहीं होती है। pandas.pydata.org/pandas-docs/stable/generated/… सामान्य तौर पर, पांडा के पास बड़ी फ़ाइलों के लिए यह और अन्य मेमोरी सेविंग तकनीक होती है।
philshem

हाँ आप सही है। मैं इसे सही करता हूं। गलती के लिये क्षमा करे।
क्रो-मैगॉन

1
आप sepएक स्तंभ सीमांकक (जो गैर- csv फ़ाइल में नहीं होनी चाहिए) को परिभाषित करने के लिए जोड़ना चाह सकते हैं
philshem

1
@ Cro-Magnon मुझे pandas.read()दस्तावेज़ में फ़ंक्शन नहीं मिल रहा है , क्या आपको इस विषय पर कोई जानकारी है?
एएमसी

6

फ़ाइल ऑब्जेक्ट द्वारा उजागर लाइनों की संख्या को पढ़ने के लिए कोई विशिष्ट विधि नहीं है।

मुझे लगता है कि सबसे आसान तरीका निम्नलिखित होगा:

lines =[]
with open(file_name) as f:
    lines.extend(f.readline() for i in xrange(N))

यह एक ऐसी चीज है जिसका मैंने वास्तव में इरादा किया था। हालांकि, मैं हालांकि सूची में प्रत्येक पंक्ति को जोड़ रहा हूं। धन्यवाद।
artdanil

4

Gnibbler शीर्ष मतदान जवाब (0:27 पर 20 नवंबर '09) के आधार पर: यह वर्ग ऑब्जेक्ट जोड़ने के लिए सिर () और पूंछ () विधि जोड़ता है।

class File(file):
    def head(self, lines_2find=1):
        self.seek(0)                            #Rewind file
        return [self.next() for x in xrange(lines_2find)]

    def tail(self, lines_2find=1):  
        self.seek(0, 2)                         #go to end of file
        bytes_in_file = self.tell()             
        lines_found, total_bytes_scanned = 0, 0
        while (lines_2find+1 > lines_found and
               bytes_in_file > total_bytes_scanned): 
            byte_block = min(1024, bytes_in_file-total_bytes_scanned)
            self.seek(-(byte_block+total_bytes_scanned), 2)
            total_bytes_scanned += byte_block
            lines_found += self.read(1024).count('\n')
        self.seek(-total_bytes_scanned, 2)
        line_list = list(self.readlines())
        return line_list[-lines_2find:]

उपयोग:

f = File('path/to/file', 'r')
f.head(3)
f.tail(3)

4

ऐसा करने के दो सबसे सहज तरीके होंगे:

  1. फ़ाइल लाइन-दर-लाइन और breakउसके बाद Nलाइनों पर Iterate करें ।

  2. next()विधि Nबार का उपयोग करके फाइल लाइन-बाय-लाइन पर इरेट करें । (यह शीर्ष उत्तर क्या करता है, इसके लिए अनिवार्य रूप से सिर्फ एक अलग वाक्यविन्यास है।)

यहाँ कोड है:

# Method 1:
with open("fileName", "r") as f:
    counter = 0
    for line in f:
        print line
        counter += 1
        if counter == N: break

# Method 2:
with open("fileName", "r") as f:
    for i in xrange(N):
        line = f.next()
        print line

लब्बोलुआब यह है कि, जब तक आप पूरी फाइल को मेमोरी में उपयोग readlines()या enumerateइंगेज नहीं करते , आपके पास बहुत सारे विकल्प हैं।


3

अपने दम पर सबसे आश्वस्त तरीका:

LINE_COUNT = 3
print [s for (i, s) in enumerate(open('test.txt')) if i < LINE_COUNT]

सूची बोध पर आधारित समाधान समारोह खुला () एक पुनरावृत्ति इंटरफ़ेस का समर्थन करता है। एन्यूमरेट () में कवर () और रिटर्न ट्यूपल्स (इंडेक्स, आइटम) शामिल हैं, फिर हम जांचते हैं कि हम एक स्वीकृत सीमा के अंदर हैं (यदि मैं <LINE_COUNT) और फिर बस परिणाम प्रिंट करें।

अजगर का आनंद लें। ;)


यह सिर्फ एक और अधिक जटिल विकल्प की तरह लगता है [next(file) for _ in range(LINE_COUNT)]
एएमसी

3

पहले 5 लाइनों के लिए, बस करें:

N=5
with open("data_file", "r") as file:
    for i in range(N):
       print file.next()

2

यदि आप कुछ ऐसा चाहते हैं, जो स्पष्ट रूप से (मैनुअल में गूढ़ सामान को देखे बिना) आयात किए बिना काम करता है और पायथन 2.x संस्करणों (2.2 से 2.6) की उचित सीमा पर काम करता है / छोड़कर और काम करता है:

def headn(file_name, n):
    """Like *x head -N command"""
    result = []
    nlines = 0
    assert n >= 1
    for line in open(file_name):
        result.append(line)
        nlines += 1
        if nlines >= n:
            break
    return result

if __name__ == "__main__":
    import sys
    rval = headn(sys.argv[1], int(sys.argv[2]))
    print rval
    print len(rval)

2

यदि आपके पास वास्तव में एक बड़ी फ़ाइल है, और यह मानकर कि आप आउटपुट को एक सुस्पष्ट सरणी बनाना चाहते हैं, तो np.genfromtxt का उपयोग करने से आपका कंप्यूटर खाली हो जाएगा। यह मेरे अनुभव में बहुत बेहतर है:

def load_big_file(fname,maxrows):
'''only works for well-formed text file of space-separated doubles'''

rows = []  # unknown number of lines, so use list

with open(fname) as f:
    j=0        
    for line in f:
        if j==maxrows:
            break
        else:
            line = [float(s) for s in line.split()]
            rows.append(np.array(line, dtype = np.double))
            j+=1
return np.vstack(rows)  # convert list of vectors to array

यदि आपके पास वास्तव में बड़ी फ़ाइल है, और यह मानकर कि आप चाहते हैं कि आउटपुट एक सुस्पष्ट सरणी हो, तो यह प्रतिबंधों का एक अनूठा समूह है, मैं वास्तव में इसके विकल्प पर कोई लाभ नहीं देख सकता।
एएमसी

1

पायथन 2.6 से शुरू होकर, आप IO बेस क्लेज़ में अधिक परिष्कृत कार्यों का लाभ उठा सकते हैं। तो ऊपर दिए गए शीर्ष उत्तर को फिर से लिखा जा सकता है:

    with open("datafile") as myfile:
       head = myfile.readlines(N)
    print head

(आपको अपनी फ़ाइल के बारे में चिंता नहीं करनी चाहिए क्योंकि एन स्टॉप से ​​कम कोई स्टॉपइंटरेशन अपवाद नहीं है।)


25
डॉक्स एन के अनुसार पढ़ने के लिए बाइट्स की संख्या है , कि लाइनों की संख्या ।
मार्क मिकोफ्की

4
N बाइट्स की संख्या है!
qed

5
वाह। घटिया नामकरण की बात करते हैं। फ़ंक्शन नाम का उल्लेख करता है linesलेकिन तर्क संदर्भित करता है bytes
आर्टऑफवर्फ

0

इसने मेरे लिए काम किया

f = open("history_export.csv", "r")
line= 5
for x in range(line):
    a = f.readline()
    print(a)

क्यों नहीं एक संदर्भ प्रबंधक का उपयोग करें? किसी भी मामले में, मैं यह नहीं देखता कि यह कई मौजूदा उत्तरों पर कैसे सुधार करता है।
एएमसी


0

fname = input("Enter file name: ")
num_lines = 0

with open(fname, 'r') as f: #lines count
    for line in f:
        num_lines += 1

num_lines_input = int (input("Enter line numbers: "))

if num_lines_input <= num_lines:
    f = open(fname, "r")
    for x in range(num_lines_input):
        a = f.readline()
        print(a)

else:
    f = open(fname, "r")
    for x in range(num_lines_input):
        a = f.readline()
        print(a)
        print("Don't have", num_lines_input, " lines print as much as you can")


print("Total lines in the text",num_lines)

-1
#!/usr/bin/python

import subprocess

p = subprocess.Popen(["tail", "-n 3", "passlist"], stdout=subprocess.PIPE)

output, err = p.communicate()

print  output

यह तरीका मेरे लिए काम करता है


यह वास्तव में एक पायथन समाधान नहीं है, हालांकि।
एएमसी

मुझे यह भी समझ नहीं आ रहा है कि आपके उत्तर में क्या लिखा है। कृपया कुछ स्पष्टीकरण जोड़ें।
अलेक्सी मारिनिचेंको
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.