- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
名为 Sample.csv 的 CSV 测试文件包含:
Brand, Price, Weight, Type
brand1, 6.05, 3.2, orange
brand2, 8.05, 5.2, orange
brand3, 6.54, 4.2, orange
brand1, 6.05, 3.2, pear
brand2, 7.05, 3.6, pear
brand3, 7.45, 3.9, pear
brand1, 5.45, 2.7, apple
brand2, 6.05, 3.2, apple
brand3, 6.43, 3.5, apple
brand4, 7.05, 3.9, apple
brand1, 8.05, 4.2, plum
brand2, 3.05, 2.2, plum
我的代码是:
import csv
headers = ['Brand','Price','Type']
with open('sample.csv', newline='') as rf:
reader = csv.DictReader(rf, delimiter=',',fieldnames=headers)
with open('output.csv', 'w', newline='') as wf:
writer = csv.DictWriter(wf, delimiter=',', extrasaction='ignore', fieldnames=headers)
writer.writerow(dict((fn,fn) for fn in writer.fieldnames))
for row in reader:
print(row)
writer.writerow(row)
我只是想在输出文件中获取品牌、价格和类型,但我得到了:
Brand,Price,Type
Brand, Price, Weight
brand1, 6.05, 3.2
brand2, 8.05, 5.2
brand3, 6.54, 4.2
brand1, 6.05, 3.2
brand2, 7.05, 3.6
brand3, 7.45, 3.9
brand1, 5.45, 2.7
brand2, 6.05, 3.2
brand3, 6.43, 3.5
brand4, 7.05, 3.9
brand1, 8.05, 4.2
brand2, 3.05, 2.2
为什么我在输出中得到的是 Weight 字段,而不是 Type 字段?
请注意,为调试添加了 writer.writerow(dict((fn,fn) for fn in writer.fieldnames)) 行,故意打印出标题两次。
最佳答案
您在 headers
中输入列名 Brand, Price, Weight
的事实不会使 DictReader
解析并仅返回这些列从源文件。它只会将它在文件中找到的列分配给这些键 - 实际上,您可以将它们命名为 First、Second、Third
,结果将是相同的。
你有两个选择:
利用你有标题行的事实,让 DictReader
根据它命名键,然后只写你想要的:
import csv
headers = ['Brand', 'Price', 'Type']
with open('sample.csv') as rf:
reader = csv.DictReader(rf, delimiter=',', skipinitialspace=True)
with open('output.csv', 'w') as wf:
writer = csv.DictWriter(wf, delimiter=',', extrasaction='ignore', fieldnames=headers)
writer.writeheader()
for row in reader:
print(row)
writer.writerow(row)
明确源中的列是什么,并明确输出中的内容 - 使用两个列表:
import csv
present_headers = ['Brand', 'Price', 'Weight', 'Type']
desired_headers = ['Brand', 'Price', 'Type']
with open('sample.csv') as rf:
reader = csv.DictReader(rf, delimiter=',', fieldnames=present_headers, skipinitialspace=True)
with open('output.csv', 'w') as wf:
writer = csv.DictWriter(wf, delimiter=', ', extrasaction='ignore', fieldnames=desired_headers)
writer.writeheader()
next(reader, None) #to skip writing the header row from the source
for row in reader:
# print(row)
writer.writerow(row)
鉴于您问题中的示例,两个选项都会产生相同的结果。
一些评论 - 问题中的示例在标题和数据行中都有分隔符 ,
后跟空格。如果它确实存在(不是复制和粘贴错误),阅读器中的选项 skipinitialspace=True
将删除它 - 否则它会成为列中数据的一部分。
另一个是不需要手动构造 DictWriter 的标题行 - 这就是 writerheader()
方法的用途。
最后,您可以在选项 2 中看到在写入数据之前调用 next(reader, None)
- 它的目的是让读取器产生第一行,就像现在一样一个普通的(不是标题),我们不想在输出中复制它。
关于python - 如何使用 DictReader 和 DictWriter 只写字段的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43697024/
我是一名优秀的程序员,十分优秀!