首先要做的事情: Python 3.5 以及下一个库:json,urllib,来自urllib导入请求
我一直试图以两种不同的方式(到目前为止)完成某些事情,我发现两者都有问题。谁能告诉我你会怎么编码呢?
代码需要使用GuildWars2的API翻译下一个词典列表中的信息,以获取每个对象的名称和位置。
ids = [{'traits': [1451, 1338, 1437], 'id': 4}, {'traits': [1471, 1482, 1711], 'id': 11}, {'traits': [2049, 2011, 1928], 'id': 18}]
首先尝试:(这很有效,此帖后面有一张图片显示结果。但是,这里的问题是它向服务器创建了12个请求,并等待要回答的时间比它应该花费的时间多。这些服务器上的每分钟请求数上限,所以我想用最少的代码对其进行编码。
specializations_items = []
for i in ids:
webpage_stored = request.urlopen("https://api.guildwars2.com/v2/specializations/"+str(i['id'])+"?lang=es").read().decode('utf8')
api_specialization_data = json.loads(webpage_stored)
api_specialization_name = api_specialization_data["name"]
translated_traits = []
numeric_traits = []
for j in i['traits']:
webpage_stored = request.urlopen("https://api.guildwars2.com/v2/traits/"+str(j)+"?lang=es").read().decode('utf8')
api_trait = json.loads(webpage_stored)
translated_traits.append(api_trait['name'])
for k in api_specialization_data['major_traits']:
if j == k:
numeric_traits.append(str(api_specialization_data['major_traits'].index(k)+1))
numeric_traits_new = []
for l in numeric_traits:
l = l.replace("9", "3").replace("8", "2").replace("7", "1").replace("6", "3").replace("5", "2").replace("4", "1")
numeric_traits_new.append(l)
specializations_items.append("[b]"+api_specialization_name+" ("+"".join(numeric_traits_new)+"):[/b] "+", ".join(translated_traits)+".")
return "\n".join(specializations_items)
第二次尝试:(很酷,只有2个请求到服务器,但这里的问题是它是循环地狱。另外,另一个问题是我甚至不确定如何分配数字信息与每个特征的定位(该部分未完成):
# Note: Each of the next 2 vars are json.loads dicts of those websites. It's unnecesary long to paste the dicts in here, so just click on the links.
api_traits = https://api.guildwars2.com/v2/traits%3Fids=1451%2C%201338%2C%201437%2C%2C1471%2C%201482%2C%201711%2C%2C2049%2C%202011%2C%201928%26lang=es
api_specializations = https://api.guildwars2.com/v2/specializations%3Fids=4%2C11%2C18%26lang=es
numeric_traits = []
for j in api_specializations:
for m in j['major_traits']:
for n in api_traits:
if n['id'] == m:
numeric_traits.append(str(j['major_traits'].index(n['id'])+1)+n['name'])
for i in ids:
for j in api_specializations:
if i['id'] == j['id']:
i['name'] = j['name']
for k in api_traits:
for l in i['traits']:
if l == k['id']:
i['traits'].remove(l)
i['traits'].append(k['name'])
print(numeric_traits) #Not finished, I don't think using so much loops is a good idea.
期望的输出:
加成:
我将提供2个不同的ID,以防您想要使用不同的ID检查不同的输出:
ids = [{'traits': [296, 325, 1510], 'id': 31}, {'traits': [232, 1502, 226], 'id': 41}, {'traits': [1952, 2015, 1986], 'id': 48}]
ids = [{'traits': [815, 816, 801], 'id': 39}, {'traits': [1876, 1844, 778], 'id': 19}, {'traits': [2020, 2031, 1919], 'id': 34}]
因此...
完成我的任务的最佳方法是什么,它不会创建不必要的服务器请求,并且在没有我变得疯狂的情况下获得所需的结果,因为循环内循环内部的循环(这也很慢) ?
答案 0 :(得分:1)
我使用requests
库从第二个代码段中获取JSON。这是一种有效的方法:
import requests
api_traits = requests.get("https://api.guildwars2.com/v2/traits%3Fids=1451%2C%201338%2C%201437%2C%2C1471%2C%201482%2C%201711%2C%2C2049%2C%202011%2C%201928%26lang=es").json()
api_specializations = requests.get("https://api.guildwars2.com/v2/specializations%3Fids=4%2C11%2C18%26lang=es").json()
traits_dict = { trait["id"]: trait["name"] for trait in api_traits }
for specialization in api_specializations:
numeric_traits = []
trait_names = []
for i, trait_id in enumerate(specialization["major_traits"]):
if trait_id in traits_dict:
numeric_traits.append(i % 3 + 1)
trait_names.append(traits_dict[trait_id])
print("{} ({}): {}.".format(specialization["name"],
"".join(map(str, numeric_traits)),
", ".join(trait_names)))
# Output:
# Fuerza (221): Fuerza restauradora, Mandoble eficaz, Potencia berserker.
# Tácticas (333): Potenciado, Potenciar aliados, Fuerza de falange.
# Berserker (111): Pendenciero aplastante, Reacción sangrienta, Rugido sangriento.
三件重要的事情:
enumerate
来避免index
查询,当您跟踪哪个特征处于哪个位置时(对于"数字特征")。i % 3
在除以3时得到余数(因为特征在三列中),然后+ 1
只返回到基于1的索引。如果代码中的任何其他内容令人困惑,请告诉我。