2009-12-22 5 views

Répondre

11

dictionnaires Python peuvent être construits en utilisant la classe dict, étant donné un iterable contenant tuples. Nous pouvons utiliser cette option conjointement avec le range builtin pour produire une collection de tuples comme dans (tous-impair point, chaque-même-point), et le transmettre à dict, de sorte que les valeurs elles-mêmes organisent en paires clé/valeur le résultat final:

dictionary = dict([(List[i], List[i+1]) for i in range(0, len(List), 2)]) 
+2

Vous pouvez prendre les '[]' s pour modifier la compréhension de liste à un générateur pour une plus grande efficacité: 'dict ((Liste [i], Liste [i + 1]) pour i dans la plage (0 , len (List), 2)) 'De cette façon, il ne générera pas de liste pour ensuite le jeter après qu'il est converti en dict. –

+0

Vous mon ami êtes un épargnant de vie, que Dieu vous bénisse. Cela fait maintenant deux heures que je suis sur –

+0

OK, la chose que j'ai laissée en premier pour la compatibilité py2.3, et aussi le fait que j'ai entendu exactement le contraire - pour les très petites collections, la construction de la liste est plus vite que les frais généraux de la construction du générateur. Je peux demander à mon collègue plus de détails à ce sujet, mais cela a du sens. – zzzeek

11

en utilisant la notation de tranche étendue:

dictionary = dict(zip(List[0::2], List[1::2])) 
3

la réponse basée gamme est plus simple, mais il y a une autre approche possible en utilisant le paquet itertools:

from itertools import izip 
dictionary = dict(izip(*[iter(List)] * 2)) 

Briser ce bas (edit: testé cette fois-ci):

# Create instance of iterator wrapped around List 
# which will consume items one at a time when called. 
iter(List) 

# Put reference to iterator into list and duplicate it so 
# there are two references to the *same* iterator. 
[iter(List)] * 2 

# Pass each item in the list as a separate argument to the 
# izip() function. This uses the special * syntax that takes 
# a sequence and spreads it across a number of positional arguments. 
izip(* [iter(List)] * 2) 

# Use regular dict() constructor, same as in the answer by zzzeeek 
dict(izip(* [iter(List)] * 2)) 

Modifier: Merci beaucoup à yeux perçants « Chris Lutz pour la double correction.

+0

Typo dans les deux dernières lignes: Il n'y a pas de fin ']' –

+0

Correction de faute de frappe par Chris (merci!) –

+0

Maintenant, vous le mettez le mauvais endroit. 'iter (List) * 2' n'est pas valide. –

0

Vous avez mentionné dans les commentaires que vous avez des entrées en double. Nous pouvons travailler avec ça. Prenez votre méthode préférée de générer la liste des tuples, et l'étendre dans une boucle for:

from itertools import izip 

dictionary = {} 
for k, v in izip(List[::2], List[1::2]): 
    if k not in dictionary: 
     dictionary[k] = set() 
    dictionary[k].add(v) 

Ou nous pourrions utiliser collections.defaultdict donc nous ne devons pas vérifier si une clé est déjà initialisé:

from itertools import izip 
from collections import defaultdict 

dictionary = defaultdict(set) 
for k, v in izip(List[::2], List[1::2]): 
    dictionary[k].add(v) 

Nous finirons par un dictionnaire où toutes les clés sont des ensembles, et les ensembles contiennent les valeurs. Cela peut ne pas convenir, car les ensembles, comme les dictionnaires, ne peuvent pas contenir de doublons. Par conséquent, si vous avez besoin d'une seule clé pour contenir deux de la même valeur, vous devez la remplacer par un n-uplet ou une liste. Mais cela devrait vous aider à démarrer.

2
d = {} 
for i in range(0, len(List), 2): 
    d[List[i]] = List[i+1] 
+0

Cest ce que je pensais, la chose la plus simple et la meilleure. :) –

Questions connexes