我知道这是简单的,但我是一个新用户到Python,所以我在这里有一个有点麻烦。 我使用Python 3的方式。
我有一个看起来像这样多个文件:
作者日期年龄,性别COLOR
Name Date Age Sex Color
Ray May 25.1 M Gray
Alex Apr 22.3 F Green
Ann Jun 15.7 F Blue
(假装这是制表符分隔的。我要补充的是,真正的文件将拥有约3000行和17-18列)
我想要做的是选择所有这些都在年龄列小于23的值的行。
在这个例子中,输出将是:
Name Date Age Sex Color
Alex Apr 22.3 F Green
Ann Jun 15.7 F Blue
这里就是我试图做的:
f = open("addressbook1.txt",'r')
line = f.readlines()
file_data =[line.split("\t")]
f.close()
for name, date, age, sex, color in file_data:
if age in line_data < 23:
g = open("college_age.txt",'a')
g.write(line)
else:
h = open("adult_age.txt",'a')
h.write(line)
现在,理想情况下,我的这些“地址簿” inputfiles 20-30,我想这个脚本来遍历所有这些,与23岁以下添加的所有条目相同的输出文件(“college_age.txt”)。 我真的不需要保持对其他行,但我不知道还有什么与他们无关。
这个脚本,当我运行它,产生一个错误。
AttributeError: 'list' object has no attribute 'split'
然后,我改变第三行:
file_data=[line.split("\t") for line in f.readlines()]
它不再给我一个错误,而是简单地做什么都没有。 这只是开始,然后开始。
任何帮助吗? :)还记得我是哑巴与Python。
我应该补充说,我的实际数据有小数和不是整数。 我已经编辑上面的数据,以反映。
这里的问题是,你正在使用readlines()
的两倍,这意味着数据被读取的第一次,然后什么都不留下的第二次。
您可以在文件中直接迭代,而无需使用readlines()
-事实上,这是更好的办法,因为它不会在一次读取整个文件。
虽然你可以做你正在尝试使用做str.split()
如你有更好的选择是使用的csv
模块 ,它是专为任务。
import csv
with open("addressbook1.txt") as input, open("college_age.txt", "w") as college, open("adult_age.txt", "w") as adult:
reader = csv.DictReader(input, dialect="excel-tab")
fieldnames = reader.fieldnames
writer_college = csv.DictWriter(college, fieldnames, dialect="excel-tab")
writer_adult = csv.DictWriter(adult, fieldnames, dialect="excel-tab")
writer_college.writeheader()
writer_adult.writeheader()
for row in reader:
if int(row["Age"]) < 23:
writer_college.writerow(row)
else:
writer_adult.writerow(row)
那么,我们在这里做什么? 首先,我们使用了with
语句用于打开文件 。 这不仅更Python和可读性,但关闭句柄给你,发生异常时也是如此。
接下来,我们创建一个DictReader
从文件中读取字典行,自动使用第一行作为字段名。 然后,我们让作家写回我们的分割文件,并在写标题。使用DictReader
是偏好的问题。 它通常用于更在您访问数据很多(当你不知道列的顺序),但它使代码漂亮可读这里。 你可以,但是,只需使用标准csv.reader()
通过该文件中的行接下来我们循环,检查年龄(我们转换为int,所以我们可以做一个数值比较)知道写的是什么文件。 在with
语句关闭了文件,对我们来说。
对于多个输入文件:
import csv
fieldnames = ["Name", "Date", "Age", "Sex", "Color"]
filenames = ["addressbook1.txt", "addressbook2.txt", ...]
with open("college_age.txt", "w") as college, open("adult_age.txt", "w") as adult:
writer_college = csv.DictWriter(college, fieldnames, dialect="excel-tab")
writer_adult = csv.DictWriter(adult, fieldnames, dialect="excel-tab")
writer_college.writeheader()
writer_adult.writeheader()
for filename in filenames:
with open(filename, "r") as input:
reader = csv.DictReader(input, dialect="excel-tab")
for row in reader:
if int(row["Age"]) < 23:
writer_college.writerow(row)
else:
writer_adult.writerow(row)
我们只是在添加一个循环来工作在多个文件。 请注意,我还添加字段名的列表。 以前我只是用领域和顺序的文件,但是我们有多个文件,我想这将是更明智的做在这里。 另一种方法是使用的第一个文件,以获得字段名。
我觉得这是更好地使用CSV模块,以读取这些文件http://docs.python.org/library/csv.html
ITYM
with open("addressbook1.txt", 'r') as f:
# with automatically closes
file_data = ((line, line.split("\t")) for line in f)
with open("college_age.txt", 'w') as g, open("adult_age.txt", 'w') as h:
for line, (name, date, age, sex, color) in file_data:
if int(age) < 23: # float() if it is not an integer...
g.write(line)
else:
h.write(line)
它看起来像文件中的数据是通过多次迭代。 但由于该生成器表达式 , file data
仅仅是一个发电机省高院文件的下一行,如果要求这样做。 而且它要求在for循环这样做。 这意味着,由for循环来自发生器检索每一个项目file_data
以及其中在请求每个文件行获取变换成一个元组保持完整的线(复印)在其组件(用于测试)。
另一种可能是
file_data = ((line, line.split("\t")) for line in iter(f.readline, ''))
- 它更接近于
readlines()
比遍历文件。 由于readline()
动作场面从遍历所有文件略有不同的背后,可能有必要这么做。
(如果你不喜欢函数式编程,您也可以手动创建一个生成函数调用readline()
直到返回一个空字符串。
如果你不喜欢嵌套发电机可言,你可以做
with open("addressbook1.txt", 'r') as f, open("college_age.txt", 'w') as g, open("adult_age.txt", 'w') as h:
for line in f:
name, date, age, sex, color = line.split("\t")
if int(age) < 23: # float() if it is not an integer...
g.write(line)
else:
h.write(line)
这不完全一样的。)