我想检查python字典中是否存在“值”,如果匹配则打印“键”。问题是值在列表中。
此脚本将根据提供的域名提供服务器名称。它将查询预定义的名称服务器并提供相应的输出。
我尝试了以下操作,但它始终为我提供相同的输出。
if [k for k, v in servers.iteritems() if answer in v]:
print "\nThe domain is in " + v + ".\n"
脚本如下。除了原始建议以外,任何其他建议都欢迎。
#!/usr/bin/python
import dns.resolver
import sys
servers = {
'UK':['127.0.0.1'],
'USA':['127.0.0.2','127.0.0.3','127.0.0.4'],
'AUS':['127.0.1.1','127.0.1.2']
}
website = sys.argv[1]
try:
nameserver = dns.resolver.Resolver(configure=False)
nameserver.nameservers = ['198.40.3.6','198.40.3.7']
answer = nameserver.query(website)[0]
answer = str(answer)
if [k for k, v in servers.iteritems() if answer in v]:
print "\nThe domain is in " + v + ".\n"
except Exception as e:
print str(e)
它应该提供正确的“密钥”,但不是。它给出了相同的输出。
答案 0 :(得分:1)
您的if
检查和后面的print
语句的逻辑是错误的。关于如何查找键,没有什么特别不正确的(尽管您可以更有效地进行操作),但是在其余的代码中根本没有使用该结果,因此这并不重要。
尝试将您的代码更改为此:
matched_keys = [k for k, v in servers.iteritems() if answer in v] # same list comp as before
if matched_keys:
print print "\nThe domain is in " + str(matched_keys) + ".\n" # or maybe use matched_keys[0]?
我上面编码的方式将打印出所有包含答案的键的列表(如果有的话)。如果确定只有一个结果,则可以使用matched_keys[0]
。
请注意,如果您希望对同一组服务器进行很多此类检查,则可能应更改数据结构,以便进行更有效的检查。当前值为O(M * N),其中M
是您需要执行的检查次数,而M
是字典中值的数目。您可以通过构造反向字典将其转换为O(M):
reversed_servers = {}
for k, v in servers.iteritems():
for address in v:
reversed_servers.setdefault(address, []).append(k) # or reversed_servers[address] = k
您只需执行一次此设置。稍后,您只需reversed_servers[answer]
就可以进行任意数量的有效查找,而无需循环。
请注意,上面的代码设置了一个字典,其中包含所有匹配键的列表,如果每个地址只能有一个(因为值是唯一的),则可以在注释中使用替代版本,它将映射直接从地址到键(没有列表)。
答案 1 :(得分:0)
尝试一下:
result = [k for k in servers.keys() if answer in servers[k]]
if result:
print "\nThe domain is in " + str(servers[result[0]]) + ".\n"
要打印相应的密钥,可以使用result[0]
。