donné 2 séquences de différentes longueurs: c'est ce que je veux p> mais je n'aime pas l'idée de En utilisant à l'envers toutes mes paramètres d'entrée, et je ne veux pas non plus ré-implémenter ma propre fonction zip. P> SO: P>
6 Réponses :
Je suggérerais:
>>> a = [1,2,3] >>> b = [4,5,6,7] >>> k = min(len(a),len(b)) >>> zip(a[-k:], b[-k:]) [(1, 5), (2, 6), (3, 7)]
Beaucoup mieux. Je rétracte ma réponse, humilié :)
@IM: Dans toute l'équité, j'ai initialement écrit "Len (A) -K" au lieu de "-k" et a adapté ma réponse après avoir vu le vôtre, alors merci.
Oui, c'est une bonne réponse. Merci!
Ou utilisez ithertools.lice code> pour éviter de prendre une copie de la liste, mais que vous devriez calculer les indices corrects car il ne peut pas prendre de valeurs négatives.
Calcul des indices lorsque vous n'êtes pas obligé de ne pas être la méthode «Pythonic».
zip(a[len(a)-min(len(a), len(b)):], b[len(b)-min(len(a), len(b)):]) but it does not look very "pythonic" :P
Ce qui suit fonctionnera même si vous ne savez pas ce qui est plus long:
>>> range(5)[-10:] [0, 1, 2, 3, 4]
J'aime ça même mieux: p
Cette réponse est intelligente, mais est trop délicate pour être considérée comme pythonique. Il serait difficile de maintenir (quiconque lisant le code doit faire un peu de déchiffrement et de perplexe pour se convaincre que le code est correct). De plus, pour de longues entrées, il n'est pas sympathique de la mémoire et fait beaucoup de copier.
Cela ne généralisera pas facilement à 3 listes ou plus, cependant.
[Mise à jour pour ajouter une possibilité de commander inversé (car je pensais que je pouvais utiliser ceci un jour)] em> en tant que générateur, vous pouvez essayer, p> Ce n'est pas obligé de prendre des copies des listes et donne, p>
Ce qui suit est plus rapide et plus clair que les autres solutions publiées: Le inversifié em> crée un itérateur ces boucles à la même vitesse que vers l'avant itération. Aucun mémoire supplémentaire (des copies complètes de l'entrée) sont produites et il n'y a pas de ralentissement des voyages lents autour du Python Eval-boucle (présent dans les autres solutions qui utilisent des indices). P> p>
Je reçois l'objet 'zip' n'est pas syndicalable code> et
'zip' objet n'a pas d'attribut 'inverse' code>
Dans Python 3, zip i> renvoie un itérateur, vous pouvez donc tout faire en une seule passe et ne convertit que dans une liste à la fin de la liste suivante: Liste (inversée (zip (a inversé (A), inversé (b)))) code>.
inversé () b> n'accepte qu'une séquence, quelle que soit la version de Python utilisée. Ensuite, dans Python 2.x, il est Liste (inversée (zip (inverser (A), inversé (b)))) code> mais dans python 3.x il est
Liste (annulée (Zip (inversé (A), inversé (B)))))) Code> Donc, dans les deux cas, il est nécessaire de créer une nouvelle liste intermédiaire lorsqu'une doublure est utilisée.
Dans la solution suivante, aucune copie de l'une des listes d'entrée n'est effectuée.
len(a) == 49500 len(b) == 50000 100.00 % Sam Hocevar, deducted normal slicing and zip k = min(len(a),len(b)) list(zip(a[-k:], b[-k:])) 99.39 % F.J. , deducted tricky slicing and zip list(zip(a[-len(b):], b[-len(a):])) 99.12 % sleeplessnerd, exactly normal slicing and zip m = min(len(a),len(b)) list(zip(a[len(a)-m:],b[len(b)-m:])) 98.10 % Sam Hocevar, exactly normal slicing and zip k = min(len(a),len(b)) list(zip(a[len(a)-k:], b[len(b)-k:])) 69.91 % eyquem 1, deducted normal slicing and listcomp m = min(len(a),len(b)) [ (a[-m+i],b[-m+i]) for i in range(m) ] 66.54 % eyquem 1 improved, exactly normal slicing and listcomp m = min(len(a),len(b) x,y = len(a)-m , len(b)-m [(a[x+i],b[y+i]) for i in range(m)] 58.94 % Raymond Hettinger, use of zip and iterator reversed list(reversed(list(zip(reversed(a),reversed(b))))) 51.29 % eyquem 2, use of zip and iterator iter list(zip(ita,itb)) 51.17 % eyquem 3, use of zip and iterators iter AND islice list(zip(iter(a),islice(b,len(b)-len(a),None))) sam1==sam2==fj==sleep==ey1==ey1bis==ey2==ey3==ray is True
Quel est faux avec
zip (inversé (A), inversé (B)) code>? Il est court, rapide et expressif (dit ce que cela signifie). Aucune des autres solutions proposées n'est aussi concise, aussi rapide, aussi claire que ce que vous avez commencé.
@RayMondhettinger - Le problème est qu'il veut maintenir l'ordre d'origine, mais en prenant les éléments les plus puissants de la liste plus grande. Il aurait besoin d'une autre chose comme la liste
(inversée (zip (inverse (A), inversée (B))) code> ou la compréhension de la liste dans la question.
Même
zip (inversé (A), inversé (B)) [:: - 1] code> est plus clair et plus rapide que les solutions postées.
Je pense que la principale à emporter est que nous pouvons choisir parmi les nombreuses façons de le faire, et il n'y a pas nécessairement une bonne réponse. Ce qui est juste pour le moment peut dépendre des choses comme combien de séquences d'intrants sont en cours de zipper ou si des personnes peuvent avoir besoin de comprendre le code après le fait, etc.
Du
inversé (liste (Zip (A, B))) code>?