我在使用for循环的正确语法时遇到了问题,无法一次打开多个gzip行的json文件,处理这些文件以仅提取某些键值对,然后保存到附加的单个csv文件中。gzip文件很大。
for循环嵌套应该如何一次打开、处理和写入一个文件?
我要么在写入之前一次打开/加载所有文件,然后最终导致内存崩溃,要么一次成功打开1,但在写入阶段出现I/O错误,因为输出文件已关闭。
directory = r"*/mydirectory*"
field_names = [
"id",
"created_at",
"user_screen_name",
"text",
"lang",
"place_country_code",
"place_name",
"coordinates",
"entities_user_mentions_screen_name",
]
tweets = []
for filename in os.scandir(directory):
if filename.path.endswith(".gz") and filename.is_file():
with gzip.open(filename, 'r') as infile,
open('clean_tweet_all_data.csv', 'a', newline="", encoding='utf-8') as outfile:
for line in infile:
tweets.append(json.loads(line)),
csv_output = csv.DictWriter(outfile, delimiter=",", fieldnames=field_names,
extrasaction="ignore")
if outfile.tell() == 0:
csv_output.writeheader(),
csv_output.writerows(get_arrays(entry) for entry in tweets)
infile.close()
outfile.close()
函数get_arrays(entry)
使json文件变平,因此用于选择键值对的field_names
列表运行良好。
我看到了三个问题,但我不知道这是否会导致您描述的问题
-
tweets
列表一直在增长,这可能会导致内存错误,您应该在写完推特后重置它(tweets = []
( -
最后不需要
infile.close()
和outfile.close()
,这已经由上下文管理器(with open ...
(负责了 -
你只向文件写入一次,因为你只在
outfile.tell() == 0
的情况下写入,也许你想把最后一行放在if
块之外?