2 votes

Utilisez la compréhension de liste pour remplacer les doublons en fonction d'une condition en utilisant une autre liste.

Il est probablement plus facile de l'illustrer par un exemple.

A = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
B = [0.1, 0.2, 0.3, 0.4, 0.01, 0.02, 0.03, 0.04, 0.001, 0.001, 0.0003, 0.0003]

J'ai les deux listes ci-dessus.

Chaque élément de A est dupliqué plusieurs fois. La multiplicité de chaque élément peut être différente (et ils n'ont pas besoin d'être ordonnés comme ici).

B contient le même nombre d'éléments que A. Je veux affecter à la liste C le plus petit élément de chaque élément dupliqué dans A (où la plus petite valeur provient des valeurs correspondantes dans la liste B. Ainsi, pour les 4 premiers éléments, ce serait 0,1, pour les 4 éléments suivants, ce serait 0,01 dans cet exemple, et pour les 4 derniers éléments, ce serait la valeur dupliquée de 0,0003 et ceci pour chacun de ces éléments dupliqués).

Je souhaiterais obtenir la liste suivante.

C = [0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]

Comme le code que j'utilise fait déjà largement appel à la compréhension des listes, j'aimerais utiliser la même approche.

Est-ce possible ?

Est-ce souhaitable ?

Je suis familier avec des conditions simples telles que

C = A[B < 0.0005]

pour donner

C = [3]

mais je n'ai pas vraiment d'idée précise sur la façon de procéder ici.

2voto

Selcuk Points 15733

Vous pouvez utiliser la méthode suivante :

>>> A = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
>>> B = [0.1, 0.2, 0.3, 0.4, 0.01, 0.02, 0.03, 0.04, 0.001, 0.001, 0.0003, 0.0003]
>>> AB = zip(A, B)
>>> AB_sorted = sorted(AB, key=lambda i: (i[0], -i[1]))
>>> AB_dict = dict(AB_sorted)
>>> C = [AB_dict[i] for i in A]
>>> C
[0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]

Cela fonctionne car lorsque vous convertissez un list de tuple à un dict les clés dupliquées sont écrasées par la dernière.

1voto

Tacratis Points 955

Si vous voulez une phrase courte, cela fonctionne, en supposant que mon commentaire soit l'interprétation correcte :

[min([B[j] for j in [ind for ind,x in enumerate(A) if x==y]]) for y in A]

Pour le décomposer, vous avez la compréhension de la liste la plus interne qui passe par les indices et les valeurs dans le fichier A puis la compréhension de la liste suivante passe en revue toutes les valeurs de la liste A à nouveau (en les stockant dans y ), et est utilisé comme condition pour la liste précédente mentionnée.
Ensuite, vous utilisez cette liste d'indices pour obtenir tous les éléments dans B (en utilisant j ) et obtenir enfin le min sur cette liste.

enumerate retourne les indices et les valeurs, en ind y x respectivement.

1voto

Jeril Points 1380

Si cela ne vous dérange pas d'utiliser une bibliothèque Python supplémentaire nommée Pandas vous pouvez faire ce qui suit :

import pandas as pd
A = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
B = [0.1, 0.2, 0.3, 0.4, 0.01, 0.02, 0.03, 0.04, 0.001, 0.001, 0.0003, 0.0003]
df = pd.DataFrame([A, B]).T.rename(columns={0: 'A', 1: 'B'})
req_dict = {key: value for key, value in df.groupby('A')['B'].min().iteritems()}
print(df['A'].replace(req_dict))

Sortie :

[0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]

0voto

Augusto Sisa Points 123

Oui, c'est possible en une seule ligne.

[min(y for x, y in zip(A, B) if z == x) for z in A]

Cela donne la liste suivante

[0.1, 0.1, 0.1, 0.1, 0.01, 0.01, 0.01, 0.01, 0.0003, 0.0003, 0.0003, 0.0003]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X