2017-02-27 2 views
1

J'utilise Google PageSpeed ​​Insights API en Python, et je suis tombé sur un problème déconcertant. L'API me présente une chaîne de format et des arguments pour cette chaîne de format, et j'ai besoin de comprendre comment formater réellement la chaîne. Le problème est que les arguments sont donnés d'une manière vraiment étrange.Python - chaîne comme clé de chaîne variable nommée Format

Voici comment les arguments de la chaîne de format me sont présentés (je montre comme une mission pour la rendre plus claire):

args = [ 
    { 
     'type': 'INT_LITERAL', 
     'value': '21', 
     'key': 'NUM_SCRIPTS' 
    }, 
    { 
     'type': 'INT_LITERAL', 
     'value': '20', 
     'key': 'NUM_CSS' 
    } 
] 

Et ceci est une chaîne de format d'échantillon, également donné moi par l'API:

format = 'Your page has {{NUM_SCRIPTS}} blocking script resources and {{NUM_CSS}} blocking CSS resources. This causes a delay in rendering your page.' 

Je sais que, parfois, les gens aiment éviter de répondre à la question posée et au lieu d'offrir une réponse adaptée à leurs croyances sur le codage « droit » et « faux », afin de réitérer, je Je reçois à la fois les arguments et la chaîne de format de l'API. Je ne les crée pas moi-même, donc je ne peux pas le faire de façon plus directe. Ce que je dois savoir est comment extraire le champ clé des dicts dans la liste d'arguments de sorte que je puisse les employer avec "".format d'une manière qui me laissera passer le champ de valeur aux arguments nommés.

Excusez-moi si cela est en quelque sorte de super évident; Je suis assez nouveau pour Python et je ne connais pas grand chose aux petits détails. J'ai fait mon devoir de diligence et cherché une réponse avant de demander, mais je n'ai rien trouvé et ce n'est pas un problème facile à rechercher.

EDIT: Je pensais que peut-être cette «liste des dicts de la chose était courante avec les API de Google ou quelque chose, que peut-être il y avait un moyen automatique d'associer les arguments (comme string.format_map). J'ai fini par le faire simplement, sans string.format.

for x in args: 
    format = format.replace('{{' + x['key'] + '}}', x['value']) 
+0

Est-ce ce que vous voulez? pour NUM_CSS '(item pour item dans args si item [" key "] ==" NUM_CSS "). next() ['value']' et pour NUM_SCRIPTS '(item pour item dans args si item [" key "] = = "NUM_SCRIPTS"). Next() ['value'] ' – Rohanil

+0

Cette liste est, franchement, un non-sens. Votre but est de rechercher des valeurs pour 'NUM_SCRIPTS' et' NUM_CSS', mais cette liste vous permet uniquement de rechercher des valeurs pour une certaine clé pour laquelle il existe une autre clé avec une autre valeur. Il devrait être 'args = {'NUM_SCRIPTS': 21, 'NUM_CSS': 20}' être même utile à distance sans un tas de mauvais code. – TigerhawkT3

+0

@Rohanil - Non, différentes chaînes de format ont des types et des nombres de variables différents, je ne peux pas coder les noms. – bpunsky

Répondre

0

Si votre chaîne de format est comme ceci:

fmt = 'blah {NUM_SCRIPTS} foo {NUM_CSS} bar' 

Et vous avez un dictionnaire des clés et des valeurs appelées args, vous pouvez formater la chaîne en utilisant le dictionnaire comme si:

fmt.format(**arg) 

Ce imprimerait:

"blah 21 foo 20 bar" 
+0

Sauf que les valeurs sont stockées dans des dicts séparés dans une liste, pas nécessairement ordonnée, donc j'ai besoin d'utiliser en quelque sorte le champ clé de chaque dict pour l'associer à l'argument nommé. – bpunsky

0

En supposant que votre chaîne format n'y avait qu'un seul jeu de crochets, vous pouvez faire:

format_dict = {} 
for d in args: 
    format_dict[d['key']] = d['value'] 

str_to_format = 'Your page has {NUM_SCRIPTS} blocking script resources and {NUM_CSS} blocking CSS resources. This causes a delay in rendering your page.' 

formatted = str_to_format.format(**format_dict) 

print(formatted) 
# Your page has 21 blocking script resources and 20 blocking CSS resources. This causes a delay in rendering your page. 

mais comme format est actuellement écrit (avec deux crochets par variable de substitution), je ne sais pas comment obtenir format() à joue bien. Si vous voulez crochets pour entourer chaque variable de substitution après la variable de substitution a été faite, vous avez besoin d'un extra set of brackets:

format_dict = {} 
for d in args: 
    format_dict[d['key']] = d['value'] 

str_to_format = 'Your page has {{{NUM_SCRIPTS}}} blocking script resources and {{{NUM_CSS}}} blocking CSS resources. This causes a delay in rendering your page.' 

formatted = str_to_format.format(**format_dict) 

print(formatted) 
# Your page has {21} blocking script resources and {20} blocking CSS resources. This causes a delay in rendering your page. 

Ainsi, selon vos besoins, ajouter ou supprimer un ensemble de supports.Pour ajouter des parenthèses, vous pouvez faire quelque chose comme ça

import re 
str_to_format = re.sub('{{|}}', lambda x: x.group(0) + x.group(0)[0], str_to_format)