วิธีอ่านไฟล์ข้อความในรายการหรืออาเรย์ด้วย Python


176

ฉันพยายามอ่านบรรทัดของไฟล์ข้อความในรายการหรืออาเรย์ในหลาม ฉันแค่ต้องสามารถเข้าถึงไอเท็มใดก็ได้ในรายการหรืออาเรย์หลังจากสร้างแล้ว

ไฟล์ข้อความถูกจัดรูปแบบดังนี้:

0,0,200,0,53,1,0,255,...,0.

ที่...ด้านบนมีไฟล์ข้อความจริงมีหลายร้อยหรือหลายพันรายการ

ฉันใช้รหัสต่อไปนี้เพื่อพยายามอ่านไฟล์ในรายการ:

text_file = open("filename.dat", "r")
lines = text_file.readlines()
print lines
print len(lines)
text_file.close()

ผลลัพธ์ที่ฉันได้รับคือ:

['0,0,200,0,53,1,0,255,...,0.']
1

เห็นได้ชัดว่ามันกำลังอ่านไฟล์ทั้งหมดลงในรายการของรายการเดียวมากกว่ารายการของแต่ละรายการ ผมทำอะไรผิดหรือเปล่า?


1
เช่นเดียวกับบันทึกย่อ ดูเหมือนว่าคำถามนี้ควรได้รับการ rephrased เป็นวิธีการอ่านไฟล์ csv ลงในรายการใน Python แต่ฉันเลื่อนไปตามความตั้งใจดั้งเดิมของ OP เมื่อ 4 ปีก่อนซึ่งฉันไม่รู้
demongolem

ที่เกี่ยวข้องน่าจะซ้ำกันของ: stackoverflow.com/questions/7844118/... , stackoverflow.com/questions/24662571/python-import-csv-to-list
บบส.


1
ในความเป็นจริงมองไปที่คำตอบด้านบนนี้เป็นซ้ำstackoverflow.com/questions/3277503/...
AMC

คำตอบ:


135

คุณจะต้องแยกสตริงของคุณออกเป็นรายการของค่าโดยใช้ split()

ดังนั้น,

lines = text_file.read().split(',')

1
ฉันคิดว่าคำตอบนี้อาจดีกว่า ... หากคุณพิจารณา.csvไฟล์หลายบรรทัด (ตามที่กล่าวไว้โดย OP) เช่นไฟล์ที่มีตัวอักษร 3 ตัวต่อแถว ( a,b,c, d,e,fและอื่น ๆ ) และใช้ขั้นตอนที่อธิบายไว้ข้างต้นสิ่งที่คุณได้รับ เป็นรายการดังนี้: ['a', 'b', 'c\nd', 'e', ... ](บันทึกรายการ'c\nd') ฉันต้องการเพิ่มปัญหาข้างต้นไม่เกี่ยวข้องกระบวนการนี้จะยุบข้อมูลจากแต่ละแถวในรายการ mega เดียวโดยทั่วไปไม่ใช่สิ่งที่ฉันต้องการเมื่อประมวลผลไฟล์ข้อมูลที่เน้นการบันทึก
gboffi

แยกจะออกจากบรรทัดใหม่ อย่าทำสิ่งนี้ใช้csvโมดูลหรือเครื่องมือแยกวิเคราะห์ที่มีอยู่
Jean-François Fabre

42

คุณยังสามารถใช้ loadtxt จำนวนมากเช่น

from numpy import loadtxt
lines = loadtxt("filename.dat", comments="#", delimiter=",", unpack=False)

1
ฉันต้องการสิ่งนี้เช่นกัน ฉันสังเกตุเห็นราสเบอร์รี่ปี่ว่ามันทำงานช้ามาก สำหรับแอพพลิเคชั่นนี้ฉันกลับไปเปิดไฟล์และอ่านทีละบรรทัด
Guus

2
สิ่งนี้มีประโยชน์ในการระบุรูปแบบด้วยdtype : data-typeพารามิเตอร์ docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html Pandas read_csv นั้นใช้งานง่ายมาก แต่ฉันไม่เห็นวิธีระบุรูปแบบ มันกำลังอ่านลอยจากไฟล์ของฉันในขณะที่ฉันต้องการสตริง ขอบคุณ @Thiru สำหรับการแสดง loadtxt
Ozgur Ozturk

1
หากไฟล์ txt มีสตริงดังนั้นควรระบุ dtype ดังนั้นจึงควรเป็นเช่น lines = loadtxt ("filename.dat", dtype = str, comments = "#", ตัวคั่น = ",",
คลาย

19

ดังนั้นคุณต้องการสร้างรายการของรายการ ... เราต้องเริ่มต้นด้วยรายการที่ว่างเปล่า

list_of_lists = []

ต่อไปเราอ่านเนื้อหาไฟล์ทีละบรรทัด

with open('data') as f:
    for line in f:
        inner_list = [elt.strip() for elt in line.split(',')]
        # in alternative, if you need to use the file content as numbers
        # inner_list = [int(elt.strip()) for elt in line.split(',')]
        list_of_lists.append(inner_list)

กรณีการใช้งานทั่วไปคือข้อมูลเรียงเป็นแนว แต่หน่วยเก็บข้อมูลของเราเป็นแถวของไฟล์ที่เราอ่านทีละรายการดังนั้นคุณอาจต้องการย้าย รายการรายการของคุณ ซึ่งสามารถทำได้ด้วยสำนวนดังต่อไปนี้

by_cols = zip(*list_of_lists)

การใช้งานทั่วไปอีกอย่างหนึ่งคือการตั้งชื่อให้กับแต่ละคอลัมน์

col_names = ('apples sold', 'pears sold', 'apples revenue', 'pears revenue')
by_names = {}
for i, col_name in enumerate(col_names):
    by_names[col_name] = by_cols[i]

เพื่อให้คุณสามารถทำงานกับรายการข้อมูลที่เป็นเนื้อเดียวกัน

 mean_apple_prices = [money/fruits for money, fruits in
                     zip(by_names['apples revenue'], by_names['apples_sold'])]

สิ่งที่ฉันเขียนส่วนใหญ่สามารถเร่งความเร็วได้โดยใช้csvโมดูลจากไลบรารีมาตรฐาน อีกโมดูลบุคคลที่สามคือpandasที่ช่วยให้คุณทำการวิเคราะห์ข้อมูลทั่วไปโดยอัตโนมัติ (แต่มีจำนวนการอ้างอิง)


อัปเดตในขณะที่ Python 2 zip(*list_of_lists)ส่งคืนรายการที่แตกต่าง (transposed) ของรายการใน Python 3 สถานการณ์มีการเปลี่ยนแปลงและzip(*list_of_lists)ส่งคืนออบเจ็กต์ zipที่ไม่สามารถถอดได้

หากคุณต้องการเข้าถึงการจัดทำดัชนีคุณสามารถใช้

by_cols = list(zip(*list_of_lists))

ที่ให้รายการของคุณใน Python ทั้งสองเวอร์ชัน

ในทางกลับกันถ้าคุณไม่ต้องการเข้าถึงการทำดัชนีและสิ่งที่คุณต้องการเพียงแค่สร้างพจนานุกรมที่จัดทำดัชนีโดยชื่อคอลัมน์วัตถุซิปจะไม่เป็นไร ...

file = open('some_data.csv')
names = get_names(next(file))
columns = zip(*((x.strip() for x in line.split(',')) for line in file)))
d = {}
for name, column in zip(names, columns): d[name] = column

OP กล่าวว่าพวกเขาต้องการรายการข้อมูลจาก CSV ไม่ใช่ "รายการของรายการ" เพียงแค่ใช้csvโมดูล ...
Blairg23

4

คำถามนี้จะถามวิธีการอ่านเนื้อหาค่าคั่นด้วยเครื่องหมายจุลภาคจากไฟล์ลงในรายการ iterable:

0,0,200,0,53,1,0,255,...,0.

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือกับcsvโมดูลดังนี้:

import csv
with open('filename.dat', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',')

ตอนนี้คุณสามารถทำซ้ำspamreaderแบบนี้ได้อย่างง่ายดาย:

for row in spamreader:
    print(', '.join(row))

ดูเอกสารประกอบสำหรับตัวอย่างเพิ่มเติม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.