87 votes

Fractionner une chaîne séparée par des points-virgules en un dictionnaire, en Python

J'ai une chaîne qui ressemble à ceci:

"Name1=Value1;Name2=Value2;Name3=Value3"

Est-il une classe intégrée/fonction en Python qui va prendre cette chaîne et la construction d'un dictionnaire, comme si j'avais fait ceci:

dict = {
    "Name1": "Value1",
    "Name2": "Value2",
    "Name3": "Value3"
}

J'ai regardé à travers les modules disponibles, mais n'arrive pas à trouver quelque chose qui correspond.


Merci, je ne sais comment faire le code moi-même, mais puisque de tels smallish solutions sont généralement mine-champs en attente de se produire (c'est à dire. quelqu'un écrit: Nom1='Valeur1=2';) etc. alors je préfère habituellement une certaine pré-testé la fonction.

Je vais le faire moi-même alors.

146voto

Brian Points 48423

Il n'y a pas builtin, mais vous pouvez accomplir cela assez simplement avec un générateur de compréhension:

s= "Name1=Value1;Name2=Value2;Name3=Value3"
dict(item.split("=") for item in s.split(";"))

[Modifier] à Partir de votre mise à jour vous indiquez que vous pourriez avoir besoin pour gérer les citant. Ce n'compliquer les choses, selon ce que le format exact que vous cherchez est (citation caractères sont acceptés, ce qui s'échapper de caractères, etc). Vous pouvez regarder le csv module pour voir si elle peut couvrir vos format. Voici un exemple: (à Noter que l'API est un peu maladroit pour cet exemple, comme le CSV est conçu pour parcourir une séquence d'enregistrements, d'où l' .next() appelle des, je fais juste regarder la première ligne. Adapter à vos besoins):

>>> s = "Name1='Value=2';Name2=Value2;Name3=Value3"

>>> dict(csv.reader([item], delimiter='=', quotechar="'").next() 
         for item in csv.reader([s], delimiter=';', quotechar="'").next())

{'Name2': 'Value2', 'Name3': 'Value3', 'Name1': 'Value1=2'}

En fonction de la structure exacte de votre format, vous pouvez avoir besoin d'écrire votre propre simple analyseur cependant.

6voto

Kyle Gibson Points 167

Cela revient à faire ce que tu voulais:

 >>> import urlparse
>>> urlparse.parse_qs("Name1=Value1;Name2=Value2;Name3=Value3")
{'Name2': ['Value2'], 'Name3': ['Value3'], 'Name1': ['Value1']}
 

-2voto

Rabarberski Points 4902

SI votre Value1, Value2 ne sont que des espaces réservés pour les valeurs réelles, vous pouvez également utiliser la fonction dict() en combinaison avec eval() .

 >>> s= "Name1=1;Name2=2;Name3='string'"
>>> print eval('dict('+s.replace(';',',')+')')
{'Name2: 2, 'Name3': 'string', 'Name1': 1}
 

C’est parce que la fonction dict() comprend la syntaxe dict(Name1=1, Name2=2,Name3='string') . Les espaces dans la chaîne (par exemple après chaque point-virgule) sont ignorés. Mais notez que les valeurs de chaîne nécessitent des guillemets.

-2voto

easytiger Points 87
easytiger $ cat test.out test.py | sed 's/^/    /'
p_easytiger_quoting:1.84563302994
{'Name2': 'Value2', 'Name3': 'Value3', 'Name1': 'Value1'}
p_brian:2.30507516861
{'Name2': 'Value2', 'Name3': "'Value3'", 'Name1': 'Value1'}
p_kyle:7.22536420822
{'Name2': ['Value2'], 'Name3': ["'Value3'"], 'Name1': ['Value1']}
import timeit
import urlparse

s = "Name1=Value1;Name2=Value2;Name3='Value3'"

def p_easytiger_quoting(s):
    d = {}
    s = s.replace("'", "")
    for x in s.split(';'):
        k, v = x.split('=')
        d[k] = v
    return d


def p_brian(s):
    return dict(item.split("=") for item in s.split(";"))

def p_kyle(s):
    return urlparse.parse_qs(s)



print "p_easytiger_quoting:" + str(timeit.timeit(lambda: p_easytiger_quoting(s)))
print p_easytiger_quoting(s)


print "p_brian:" + str(timeit.timeit(lambda: p_brian(s)))
print p_brian(s)

print "p_kyle:" + str(timeit.timeit(lambda: p_kyle(s)))
print p_kyle(s)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X