Python - 需要帮助将字典字典写入 CSV 文件
Posted
技术标签:
【中文标题】Python - 需要帮助将字典字典写入 CSV 文件【英文标题】:Python - Need help writing dictionary of dictionaries to CSV file 【发布时间】:2020-10-17 05:49:55 【问题描述】:我对 Python 还是很陌生,我正在尝试创建一个报告,该报告需要一个包含信息和错误消息的系统日志,然后将它们放入一个包含 3 列的 CSV 文件中。第一列应包含用户名,第二列应包含与用户名相关的错误消息数量,最后一列应包含与用户名相关的信息消息数量。
然后我会将 CSV 转换为 excel 以便我可以得到这个结果:
为此,我有以下代码:
import re
import csv
import operator
from collections import Counter
test_list = []
test_list2 = []
with open(r"syslog.txt", "r") as log:
for i in log:
if re.findall("ERROR.*", i):
test_list.append(re.findall("ticky:.*ERROR [\w '].*\(([\w\.]*).*$", i))
elif re.findall("INFO.*", i):
test_list2.append(re.findall("ticky:.*INFO [\w '].*\(([\w\.]*).*$", i))
flattened = [val for sublist in test_list for val in sublist]
test_dict = Counter(flattened)
flattened2 = [val for sublist in test_list2 for val in sublist]
test_dict2 = Counter(flattened2)
error = sorted(test_dict.items(), key=operator.itemgetter(0))
info = sorted(test_dict2.items(), key=operator.itemgetter(0))
username = 'info': info, 'error': error
users = 'username': username
userNames = username.get("error", "")
info_amount = username.get("info", "")
error_amount = username.get("error", "")
usernames_final = [x[0] for x in userNames]
info_message_amount = [x[1] for x in info_amount]
error_message_amount = [x[1] for x in error_amount]
with open('emails.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["User", "Info", "Error"])
for (a, b, c) in zip(usernames_final, info_message_amount, error_message_amount):
csvfile.write(a + "," + str(b) + "," + str(c) + '\n')
下面是 syslog.txt 中的几行:
Jan 31 06:59:57 ubuntu.local ticky: INFO Commented on ticket [#7255] (oren)
Jan 31 07:59:56 ubuntu.local ticky: ERROR Ticket doesn't exist (flavia)
Jan 31 08:01:40 ubuntu.local ticky: ERROR Tried to add information to closed ticket (jackowens)
Jan 31 08:03:19 ubuntu.local ticky: INFO Closed ticket [#1712] (britanni)
Jan 31 08:22:37 ubuntu.local ticky: INFO Created ticket [#2860] (mcintosh)
Jan 31 08:28:07 ubuntu.local ticky: ERROR Timeout while retrieving information (montanap)
我已经设法得到一个看起来像这样的字典(它是“用户”变量):
'username': 'info': [('ac', 2),
('ahmed.miller', 2),
('blossom', 2),
('breee', 1),
('britanni', 1),
('enim.non', 2),
('jackowens', 2),
('kirknixon', 2),
('mcintosh', 4),
('mdouglas', 2),
('noel', 6),
('nonummy', 2),
('oren', 2),
('rr.robinson', 2),
('sri', 2)],
'error': [('ac', 2),
('ahmed.miller', 4),
('blossom', 6),
('bpacheco', 2),
('breee', 5),
('britanni', 1),
('enim.non', 3),
('flavia', 5),
('jackowens', 4),
('kirknixon', 1),
('mai.hendrix', 3),
('mcintosh', 3),
('mdouglas', 3),
('montanap', 4),
('noel', 3),
('nonummy', 3),
('oren', 7),
('rr.robinson', 1),
('sri', 2),
('xlg', 4)]
它包含我需要的所有信息并且已排序,但我不知道如何将其制成符合我标准的 CSV。
我从它写入 csv 的最后一个代码块中得到的结果几乎是正确的,只是它没有提取所有用户名,并且它还仅向某些用户的信息消息添加 1。我认为它只迭代存在于 info_message_amount 和 error_message_amount 中的用户名,而不是所有用户名,这就是为什么我只获得一些用户。对于额外的数字,我不知道。
如果有人可以帮助我解决这个问题,我将非常感激,我只是无法弄清楚。
谢谢!
编辑:我还应该提到这是我正在做的一个练习,他们希望我在不使用 pandas 的情况下完成这个。只应使用已导入的模块/包。 pandas我们还没有介绍,所以不知道怎么用。
【问题讨论】:
这能回答你的问题吗? create pandas dataframe from dictionary of dictionaries @MLavrentyev 这确实看起来与我正在尝试做的完全一样,但我不明白,所以我不知道如何在我的代码中实现它。 【参考方案1】:感谢所有提示!
我可以通过使用它来使其工作:
usernames_final = [x[0] for x in userNames]
info_message_amount = [x[1] for x in info_amount]
info_users = [x[0] for x in info_amount]
error_message_amount = [x[1] for x in error_amount]
with open('emails.csv', 'w') as csvfile:
i = 0
writer = csv.writer(csvfile)
writer.writerow(["User", "Info", "Error"])
for user, error in zip(usernames_final, error_message_amount):
if user in info_users:
csvfile.write(user + "," + str(info_message_amount[i]) + "," + str(error) + '\n')
i += 1
else:
csvfile.write(user + "," + "0" + "," + str(error) + '\n')
【讨论】:
【参考方案2】:因此,提供您在问题中发布的字典示例,可能是这样的(我假设字典名为“dic”)不需要熊猫:
tupla_1=()
tupla_2=()
err_list=dic['username']['error']
info_list=dic['username']['info']
for i in range(len(err_list)):
look_for=err_list[i][0]
found=False
for j in range(len(info_list)):
if look_for==info_list[j][0]:
found=True
tupla_1=err_list[i]
tupla_1=tupla_1+(info_list[j][1],)
err_list[i]=tupla_1
if found==False:
tupla_2=err_list[i]
tupla_2=tupla_2+(0,)
err_list[i]=tupla_2
print(err_list)
csvstr=''
for i in range(len(err_list)):
csvstr+=str(err_list[i][0])+","+str(err_list[i][2])+","+str(err_list[i][1])+"\n"
f = open("emails.csv", "w")
f.write(csvstr)
【讨论】:
啊,谢谢!我知道你在做什么,据我所知,这应该有效。不过,我能够找到不同的解决方案,请查看我发布的答案。【参考方案3】:也许您可以尝试手动编写 csv 而不是使用库,因为 CSV 是一种简单的格式。像这样的:
csvstr=''
for i in range(len(userNames)):
csvstr+=userNames[i]+","+info[i]+","+error[i]+"/n"
f = open("emails.csv", "w")
f.write(csvstr)
【讨论】:
感谢您的提示!这绝对可以工作,但似乎仍然存在一个问题,即并非所有用户都在两个列表中。因此,如果用户只有错误消息而没有信息消息,则必须在该行中写入 0。使用此代码我收到错误:“IndexError: list index out of range”以上是关于Python - 需要帮助将字典字典写入 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章