Si vous n'avez pas Python 2.6 ou supérieur, l'alternative est d'écrire une boucle for explicite:
def set_list_intersection(set_list):
if not set_list:
return set()
result = set_list[0]
for s in set_list[1:]:
result &= s
return result
set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print set_list_intersection(set_list)
# Output: set([1])
Vous pouvez également utiliser reduce
:
set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])
Cependant, de nombreux programmeurs Python ne l'aiment pas, y compris Guido lui - même :
Il y a environ 12 ans, Python a acquis lambda, Reduce (), filter () et map (), gracieuseté (je crois) d'un pirate Lisp qui les a manqués et a soumis des correctifs de travail. Mais, malgré la valeur PR, je pense que ces fonctionnalités devraient être coupées de Python 3000.
Alors maintenant, réduisez (). C'est en fait celui que j'ai toujours détesté le plus, car, à l'exception de quelques exemples impliquant + ou *, presque chaque fois que je vois un appel Reduce () avec un argument de fonction non trivial, je dois saisir un stylo et du papier pour diagramme ce qui est réellement introduit dans cette fonction avant de comprendre ce que la fonction de réduction () est censée faire. Donc, dans mon esprit, l'applicabilité de Reduce () est à peu près limitée aux opérateurs associatifs, et dans tous les autres cas, il est préférable d'écrire explicitement la boucle d'accumulation.
reduce
est "limitée aux opérateurs associatifs", ce qui est applicable dans ce cas.reduce
est très souvent difficile à comprendre, mais ce&
n'est pas si mal.set_list and reduce(set.intersection, set_list)
result
est vide.Ici, je propose une fonction générique pour l'intersection de plusieurs ensembles en essayant de tirer parti de la meilleure méthode disponible:
Guido pourrait ne pas aimer
reduce
, mais je l'aime un peu :)la source
sets
au lieu d'essayer d'accédersets[0]
et d'attraper leIndexError
.a_set
est utilisé lors du retour final.return reduce(sets[0], sets[1:]) if sets else set()
?try
/except
. C'est une odeur de code, est inefficace et peut cacher d'autres problèmes.La réponse de Jean-François Fabre set.intesection (* list_of_sets) est certainement la plus pyhtonique et est à juste titre la réponse acceptée.
Pour ceux qui souhaitent utiliser réduire, les éléments suivants fonctionneront également:
reduce(set.intersection, list_of_sets)
la source