Python adding list to the values of a dictionary TypeError: unhashable type: 'list'
Python adding list to the values of a dictionary TypeError: unhashable type: 'list'
我正在尝试比较两个文件,然后将最终结果写入字典 "dns_dic",但出现此错误:
这是我正在使用的脚本:
g = open('/data/data/A.1/ap2014-2dom.txt','r')
f = open('/data/data/A.1/test','r')
dns_dic=defaultdict(set)
d = defaultdict(set)
psl = PublicSuffixList()
for line in g:
line = line.strip('\n')
domain,bl_date= line.split('|')
bl_date = int(bl_date)
if domain in d:
d[domain].add(bl_date)
else:
d[domain] = set([bl_date])
for n, line in enumerate(f):
line = line.strip('')
try:
jdata = json.loads(line)
dom = psl.get_public_suffix(jdata.get('rrname'))
except:
pass
if dom in d:
if dom not in dns_dic:
for i in d[domain]:
if jdata.get('time_first') <= i <= jdata.get('time_last'):
ip = jdata.get('rdata') # ip one or more ips in a list
if dom in dns_dic:
dns_dic[dom].add(ip)
else:
dns_dic[dom] = set(ip)
print dns_dic
这是 g 的样子:
0001211.com|1407101455
000a.biz|1399553282
000a.biz|1400084462
000a.biz|1400243222
这就是 f 的样子:
{"rrname":"c.000a.biz.","time_last":1400243400,"time_first":1388645949,"rdata":["50.21.180.100"]}
{"rrname":"c.000a.biz.","time_last":1389133600,"time_first":1389133600,"rdata":["50.21.180.100"]}
{"rrname": "0001211.com.","time_last":1407101755,"time_first":1389074193,"rdata":["50.21.180.100"]}
有人知道我为什么会收到这个错误吗?我认为这是因为我将 ip(rdata) 列表添加到 dns_dic ,但我不确定,我找不到解决方案。
您正在尝试将 列表 放入您的集合中:
dns_dic[dom].add(ip)
ip
是这里的列表;它取自 jdata
:
ip = jdata.get('rdata')
定义为列表的地方:
"rdata":["50.21.180.100"]
集合的内容必须是可散列的,而列表不是。
您可能想使用 set.update()
来添加该列表的所有 元素 :
dns_dic[dom].update(ip)
将变量重命名为 ips
(复数)会更好地反映它是一个列表。
您已经为 dns_dic
使用了 defaultdict(set)
对象,因此无需测试 dom in dns_dic
;您可以始终使用 update()
:
if jdata.get('time_first') <= i <= jdata.get('time_last'):
dns_dic[dom].update(jdata.get('rdata', []))
如果你想实际构建这样一个集合,你需要删除以下行:
if dom not in dns_dic:
因为这意味着您忽略该域中的其他条目。
这使得你的第二个循环:
for n, line in enumerate(f):
line = line.strip('')
try:
jdata = json.loads(line)
except ValueError:
continue # ignore invalid or empty lines
dom = psl.get_public_suffix(jdata.get('rrname'))
for i in d.get(domain, []):
if jdata['time_first'] <= i <= jdata['time_last']:
dns_dic[dom].update(jdata['rdata'])
我正在尝试比较两个文件,然后将最终结果写入字典 "dns_dic",但出现此错误:
这是我正在使用的脚本:
g = open('/data/data/A.1/ap2014-2dom.txt','r')
f = open('/data/data/A.1/test','r')
dns_dic=defaultdict(set)
d = defaultdict(set)
psl = PublicSuffixList()
for line in g:
line = line.strip('\n')
domain,bl_date= line.split('|')
bl_date = int(bl_date)
if domain in d:
d[domain].add(bl_date)
else:
d[domain] = set([bl_date])
for n, line in enumerate(f):
line = line.strip('')
try:
jdata = json.loads(line)
dom = psl.get_public_suffix(jdata.get('rrname'))
except:
pass
if dom in d:
if dom not in dns_dic:
for i in d[domain]:
if jdata.get('time_first') <= i <= jdata.get('time_last'):
ip = jdata.get('rdata') # ip one or more ips in a list
if dom in dns_dic:
dns_dic[dom].add(ip)
else:
dns_dic[dom] = set(ip)
print dns_dic
这是 g 的样子:
0001211.com|1407101455
000a.biz|1399553282
000a.biz|1400084462
000a.biz|1400243222
这就是 f 的样子:
{"rrname":"c.000a.biz.","time_last":1400243400,"time_first":1388645949,"rdata":["50.21.180.100"]}
{"rrname":"c.000a.biz.","time_last":1389133600,"time_first":1389133600,"rdata":["50.21.180.100"]}
{"rrname": "0001211.com.","time_last":1407101755,"time_first":1389074193,"rdata":["50.21.180.100"]}
有人知道我为什么会收到这个错误吗?我认为这是因为我将 ip(rdata) 列表添加到 dns_dic ,但我不确定,我找不到解决方案。
您正在尝试将 列表 放入您的集合中:
dns_dic[dom].add(ip)
ip
是这里的列表;它取自 jdata
:
ip = jdata.get('rdata')
定义为列表的地方:
"rdata":["50.21.180.100"]
集合的内容必须是可散列的,而列表不是。
您可能想使用 set.update()
来添加该列表的所有 元素 :
dns_dic[dom].update(ip)
将变量重命名为 ips
(复数)会更好地反映它是一个列表。
您已经为 dns_dic
使用了 defaultdict(set)
对象,因此无需测试 dom in dns_dic
;您可以始终使用 update()
:
if jdata.get('time_first') <= i <= jdata.get('time_last'):
dns_dic[dom].update(jdata.get('rdata', []))
如果你想实际构建这样一个集合,你需要删除以下行:
if dom not in dns_dic:
因为这意味着您忽略该域中的其他条目。
这使得你的第二个循环:
for n, line in enumerate(f):
line = line.strip('')
try:
jdata = json.loads(line)
except ValueError:
continue # ignore invalid or empty lines
dom = psl.get_public_suffix(jdata.get('rrname'))
for i in d.get(domain, []):
if jdata['time_first'] <= i <= jdata['time_last']:
dns_dic[dom].update(jdata['rdata'])