J'ai une liste de chaînes comme celle-ci:
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
Quel est le moyen le plus court de trier X en utilisant les valeurs de Y pour obtenir la sortie suivante?
["a", "d", "h", "b", "c", "e", "i", "f", "g"]
L'ordre des éléments ayant la même "clé" n'a pas d'importance. Je peux recourir à l'utilisation de for
constructions mais je suis curieux de savoir s'il existe un chemin plus court. Aucune suggestion?
Réponses:
Code le plus court
Exemple:
En général
Expliqué:
zip
les deuxlist
art.list
fonction de l'zip
utilisationsorted()
.list
.Pour plus d'informations sur la façon de définir \ utiliser le
key
paramètre ainsi que lasorted
fonction en général, jetez un œil à ceci .la source
Compressez les deux listes, triez-les, puis prenez les parties que vous souhaitez:
Combinez-les ensemble pour obtenir:
la source
X
c'est une liste destr
, mais soyez prudent s'il y a une possibilité qui<
n'est pas définie pour certaines paires d'articles dansX
, par exemple - si certains d'entre eux l'étaientNone
AttributeError: 'zip' object has no attribute 'sort'
c'est ce que je reçois à partir de maintenant.sorted(zip(...))
devrait toujours fonctionner, ou:them = list(zip(...)); them.sort()
De plus, si cela ne vous dérange pas d'utiliser des tableaux numpy (ou si vous avez déjà affaire à des tableaux numpy ...), voici une autre bonne solution:
Je l'ai trouvé ici: http://scienceoss.com/sort-one-list-by-another-list/
la source
sortedArray1= array1[array2.argsort()]
. Et cela facilite également le tri de plusieurs listes par une colonne particulière d'un tableau 2D: par exemple,sortedArray1= array1[array2[:,2].argsort()]
pour trier le tableau1 (qui peut avoir plusieurs colonnes) par les valeurs de la troisième colonne du tableau2.La solution la plus évidente pour moi est d'utiliser le
key
mot - clé arg.Notez que vous pouvez le raccourcir en une ligne si vous souhaitez:
la source
En fait, je suis venu ici pour trier une liste par liste où les valeurs correspondaient.
la source
index
effectuera une recherche O (N) surlist_a
résultant en unO(N² log N)
tri.more_itertools
dispose d'un outil pour trier les itérables en parallèle:Donné
Démo
la source
J'aime avoir une liste d'indices triés. De cette façon, je peux trier n'importe quelle liste dans le même ordre que la liste source. Une fois que vous avez une liste d'indices triés, une simple compréhension de liste fera l'affaire:
Notez que la liste d'index triée peut également être obtenue en utilisant
numpy.argsort()
.la source
Une autre alternative, combinant plusieurs des réponses.
Afin de travailler pour python3:
la source
zip, trier par la deuxième colonne, retourner la première colonne.
la source
list(zip(*sorted(zip(X,Y), key=operator.itemgetter(1))))[0]
Une doublure rapide.
Dites que vous voulez que la liste a corresponde à la liste b.
Cela est utile lorsque vous devez commander une liste plus petite avec des valeurs plus grandes. En supposant que la liste plus grande contient toutes les valeurs de la liste plus petite, cela peut être fait.
la source
X
etY
?index
effectuera une recherche O (N) surlist_b
résultant en unO(N² log N)
tri.Vous pouvez créer un
pandas Series
, en utilisant la liste principale asdata
et l'autre liste asindex
, puis trier simplement par l'index:production:
la source
Voici la réponse de Whatangs si vous souhaitez obtenir les deux listes triées (python3).
N'oubliez pas que Zx et Zy sont des tuples. Je me demande également s'il existe une meilleure façon de le faire.
Avertissement: si vous l'exécutez avec des listes vides, il se bloque.
la source
J'ai créé une fonction plus générale, qui trie plus de deux listes en fonction d'une autre, inspirée de la réponse de @ Whatang.
la source
Pour obtenir des valeurs uniques présentes dans
list2
Pour trouver l'emplacement de l'index dans
list2
L'emplacement de l'index dans
list2
est suivi à l'aide decur_loclist
[0, 3, 7, 1, 2, 4, 8, 5, 6]
la source
Il s'agit d'une vieille question, mais certaines des réponses que je vois publiées ne fonctionnent pas car elles
zip
ne sont pas scriptables. Les autres réponses n'ont pas pris la peine deimport operator
fournir plus d'informations sur ce module et ses avantages ici.Il existe au moins deux bons idiomes pour ce problème. En commençant par l'exemple d'entrée que vous avez fourni:
Utilisation de l' idiome " Décorer-Trier-Décorer "
Ceci est également connu sous le nom de Schwartzian_transform après R. Schwartz qui a popularisé ce modèle en Perl dans les années 90:
Notez que dans ce cas
Y
etX
sont triés et comparés lexicographiquement. Autrement dit, les premiers éléments (deY
) sont comparés; et s'ils sont identiques, les deuxièmes éléments (deX
) sont comparés, etc. Cela peut créer des sorties instables sauf si vous incluez les index de liste d'origine pour l'ordre lexicographique afin de conserver les doublons dans leur ordre d'origine.Utilisation du
operator
moduleCela vous donne un contrôle plus direct sur la façon de trier l'entrée, de sorte que vous pouvez obtenir une stabilité de tri en indiquant simplement la clé spécifique à trier. Voir plus d'exemples ici .
la source