Cela semble évident, mais il me manque la bonne forme.
Étant donné une liste de chaînes comme
fields = ["format = rassemblantnutsinmay", "appareil = TESTX "]
J'essaie d'écrire une compréhension de dictée pour faire un dictionnaire des champs:
items = {" format ":" "," device ":" TESTX}
J'ai pour le moment:
_kv_seperator = re.compile(r"\s*=\s*") items = {fk: fv for f in fields for [fk, fv] in _kv_seperator.split(f)}
mais j'obtiens l'erreur:
_kv_seperator.split (f)
ValueError: trop de valeurs à décompresser (attendu 2)
Corrections, s'il vous plaît!
5 Réponses :
Si le format est fixe, je suggère d'utiliser .split ():
fields = ["format = gatheringnutsinmay", "device = TESTX"] result = {} for f in fields: f = f.split(" = ") result[f[0]] = f[1] print(result)
Vous n'avez pas besoin de la deuxième boucle for, une façon de voir votre compréhension du dictionnaire est la suivante:
items = {fk: fv for fk, fv in (_kv_seperator.split(f) for f in fields)}
Quand vous écrivez:
items = dict(map(_kv_seperator.split, fields)) print(items)
Guido n'a-t-il pas dit qu'en utilisant les compréhensions, nous pourrions nous débarrasser de map () et filter ()? :-) En termes pratiques, votre deuxième option est la meilleure et préserve l'expression regex - nécessaire car ces chaînes proviennent parfois de fichiers édités par l'utilisateur final ....
À mon humble avis, il y a un contexte où l'utilisation de la carte est plus claire, un exemple est celui-ci
Je ne pense pas que cette partie de la réponse soit correcte: Vous dites à Python que vous attendez un itérable composé de 2-tuples, mais en fait _kv_seperator.split (f) ne renvoie qu'un seul tuple, d'où l'erreur: ValueError: too beaucoup de valeurs à décompresser (attendues 2)
Je ne veux pas mettre trop d'efforts mentaux pour décompresser cette compréhension imbriquée, mais vous pouvez rapidement vous le prouver en faisant: {l: l for f in champs pour l dans _kv_seperator.split (f)}
- vous verrez ce qui se passe réellement.
@lvrf Ce que vous mettez n'est pas équivalent à ce que j'ai écrit, _kv_seperator.split (f)
renvoie un seul tuple, mais un tuple est un itérable en soi. En fait, split renvoie une liste, mais pour les besoins de ma réponse, c'est équivalent
Mon point était que pour autant que je sache, il est parfaitement légal de décompresser la sortie de _kv_seperator.split
dans [fk, fv]
. Ainsi, par exemple: >>> fields = ["format = collectenutsinmay", "device = TESTX"] >>> [k1, k2] = _kv_seperator.split (fields [0]) >>> k1, k2 ( 'format', 'rassembler des noix en mai')
Bien sûr, vous pouvez les décompresser car ce sont deux éléments, mais vous ne pouvez pas le faire en boucle
items = { i.split('=')[0]:i.split('=')[1] for i in fields}
Si vous voulez une seule ligne, cela fera l'affaire:
items = {k:v for k,v in (sp.split(' = ') for sp in fields)}
vous pouvez utiliser le code ci-dessous au lieu d'utiliser rex:
fields = ["format = gatheringnutsinmay", "device = TESTX"] items = {f.split(" = ")[0]: f.split(" = ")[1] for f in fields} items
J'espère que cela vous a aidé.
Si vous voulez utiliser une compréhension de dict, utilisez simplement la méthode split str au lieu de regex:
{s.split ('=') [0]: s.split ('=') [1] for s in fields}
Pourquoi la méthode re split ne fonctionne-t-elle pas? Il renvoie une liste correcte?
['format', 'rassembler des noix en mai']
Je ne pense pas que votre compréhension imbriquée fasse ce que vous pensez. Il semble que vous essayez de décompresser les chaînes dans [fk, fv] et si la chaîne est plus longue que 2 caractères, elle renverra l'erreur que vous voyez. Si vous souhaitez utiliser le package re, vous pouvez faire quelque chose comme:
{k: v pour k, v dans [_kv_seperator.split (f) pour f dans les champs]}
. Personnellement, j'essaierais de rester simple et de ne pas introduire le paquet re.