ইতিমধ্যে অনেক ভাল উত্তর রয়েছে, তবে যদি আপনার পুরো ফাইলটি একটি লাইনে থাকে এবং আপনি এখনও "সারিগুলি" (স্থির-আকারের ব্লকের বিপরীতে) প্রক্রিয়া করতে চান তবে এই উত্তরগুলি আপনাকে সাহায্য করবে না।
99% সময়কালে, ফাইলগুলি লাইন দ্বারা প্রক্রিয়াকরণ করা সম্ভব। তারপরে, এই উত্তরে যেমন পরামর্শ দেওয়া হয়েছে , আপনি ফাইলটি নিজেই অলস জেনারেটর হিসাবে ব্যবহার করতে পারেন:
with open('big.csv') as f:
for line in f:
process(line)
যাইহোক, আমি একবার খুব বড় (প্রায়) একক লাইন ফাইলে দৌড়েছি, যেখানে সারি বিভাজক আসলে ছিল না '\n'
তবে '|'
।
- লাইনে লাইনে পড়া কোনও বিকল্প ছিল না, তবে আমার এখনও এটি সারি সারি প্রক্রিয়াকরণ করা দরকার।
- রূপান্তর
'|'
করার '\n'
আগে প্রক্রিয়াকরণ প্রশ্ন আউট ছিল, কারণ এই CSV ক্ষেত্র কিছু অন্তর্ভুক্ত '\n'
(বিনামূল্যে টেক্সট ব্যবহারকারীর ইনপুট)।
- CSV গ্রন্থাগার ব্যবহার এছাড়াও ছিটকে করা হয়েছে কারণ যে, liberal এর সংক্ষিপ্ত রূপ প্রথম সংস্করণে অন্তত এটা হার্ডকোডেড হয় লাইন দ্বারা ইনপুট লাইন পড়তে ।
এই ধরণের পরিস্থিতিতে আমি নিম্নলিখিত স্নিপেট তৈরি করেছি:
def rows(f, chunksize=1024, sep='|'):
"""
Read a file where the row separator is '|' lazily.
Usage:
>>> with open('big.csv') as f:
>>> for r in rows(f):
>>> process(row)
"""
curr_row = ''
while True:
chunk = f.read(chunksize)
if chunk == '': # End of file
yield curr_row
break
while True:
i = chunk.find(sep)
if i == -1:
break
yield curr_row + chunk[:i]
curr_row = ''
chunk = chunk[i+1:]
curr_row += chunk
আমি আমার সমস্যা সমাধানের জন্য এটি সফলভাবে ব্যবহার করতে সক্ষম হয়েছি। বিভিন্ন আকারের আকারের সাথে এটি ব্যাপকভাবে পরীক্ষা করা হয়েছে।
যারা নিজেকে বোঝাতে চান তাদের জন্য টেস্ট স্যুট।
test_file = 'test_file'
def cleanup(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
os.unlink(test_file)
return wrapper
@cleanup
def test_empty(chunksize=1024):
with open(test_file, 'w') as f:
f.write('')
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 1
@cleanup
def test_1_char_2_rows(chunksize=1024):
with open(test_file, 'w') as f:
f.write('|')
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 2
@cleanup
def test_1_char(chunksize=1024):
with open(test_file, 'w') as f:
f.write('a')
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 1
@cleanup
def test_1025_chars_1_row(chunksize=1024):
with open(test_file, 'w') as f:
for i in range(1025):
f.write('a')
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 1
@cleanup
def test_1024_chars_2_rows(chunksize=1024):
with open(test_file, 'w') as f:
for i in range(1023):
f.write('a')
f.write('|')
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 2
@cleanup
def test_1025_chars_1026_rows(chunksize=1024):
with open(test_file, 'w') as f:
for i in range(1025):
f.write('|')
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 1026
@cleanup
def test_2048_chars_2_rows(chunksize=1024):
with open(test_file, 'w') as f:
for i in range(1022):
f.write('a')
f.write('|')
f.write('a')
# -- end of 1st chunk --
for i in range(1024):
f.write('a')
# -- end of 2nd chunk
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 2
@cleanup
def test_2049_chars_2_rows(chunksize=1024):
with open(test_file, 'w') as f:
for i in range(1022):
f.write('a')
f.write('|')
f.write('a')
# -- end of 1st chunk --
for i in range(1024):
f.write('a')
# -- end of 2nd chunk
f.write('a')
with open(test_file) as f:
assert len(list(rows(f, chunksize=chunksize))) == 2
if __name__ == '__main__':
for chunksize in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]:
test_empty(chunksize)
test_1_char_2_rows(chunksize)
test_1_char(chunksize)
test_1025_chars_1_row(chunksize)
test_1024_chars_2_rows(chunksize)
test_1025_chars_1026_rows(chunksize)
test_2048_chars_2_rows(chunksize)
test_2049_chars_2_rows(chunksize)
f = open('really_big_file.dat')
কোনও পয়েন্টার ছাড়া কোনও স্মৃতি ব্যয় না করে? (আমি বোঝাতে চাইছি যে মেমরিটি ফাইলের আকার নির্বিশেষে একই রকম?) আমি যদি f.readline () এর পরিবর্তে urllib.readline () ব্যবহার করি তবে এটি কীভাবে পারফরম্যান্সে প্রভাব ফেলবে?