J'ai la liste suivante:
indices_to_remove_1 : [0,1,2,3,....,600] indices_to_remove_2 : [800,801,802,....,1200] indices_to_remove_3 : [1600,1601,1602,....., 1800]
J'ai essentiellement 3 sous-ensembles d'indices consécutifs:
Je voudrais créer 3 petites listes différentes qui n'incluront que des nombres consécutifs.
Résultat attendu:
indices_to_remove: [0,1,2,3,..,600,800,801,802,....,1200,1600,1601,1602,...,1800]
P.S: Les nombres sont arbitraires et aléatoires; de plus, je peux rencontrer plus de 3 sous-ensembles ou moins.
3 Réponses :
J'aime utiliser des générateurs pour ce genre de problème. Vous pouvez procéder comme suit:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90] [160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170]
indices_to_remove = ( list(range(0, 11)) + list(range(80, 91)) + list(range(160, 171)) ) for i in split_non_consequtive(indices_to_remove): print(i)
def split_non_consequtive(data): data = iter(data) val = next(data) chunk = [] try: while True: chunk.append(val) val = next(data) if val != chunk[-1] + 1: yield chunk chunk = [] except StopIteration: if chunk: yield chunk
Notez que vous pouvez utiliser itertools.groupby
ici ... C'est un peu difficile à faire mais une astuce assez intéressante: [[el [1] for el in g] for k, g in itertools.groupby (enumerate (indices_to_remove), lambda L: L [1] - L [0])]
: p
@JonClements, très bien!
Merci @StephenRauch. Cependant, existe-t-il un moyen possible de modifier le code pour supprimer les trois premier et dernier éléments de chaque sous-liste produite?
print (i [3: -3])
ou yield chunk [3: -3]
@Stephen Je me souviens vaguement qu'il s'agissait d'un exemple de recette itertools
dans la documentation Python 2.5 ou quelque chose comme ça, mais je ne l'ai pas vu depuis ... Je pensais juste que vous pourriez l'apprécier :)
Une autre méthode consiste à utiliser more_itertools.consecutive_groups
:
( a utilisé la liste de @ Stephen comme exemple ):
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90] [160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170]
import more_itertools as mit for group in mit.consecutive_groups(indices_to_remove): print(list(group))
Merci, @ anky_91 pour votre réponse, mais j'aimerais savoir s'il serait possible d'éliminer les deux premier et dernier éléments de toutes les sous-listes que nous avons créées.
Merci encore. @ anky_91 Une dernière question: je voudrais savoir s'il existe un moyen de combiner toutes les sous-listes créées dans une grande liste, mon objectif principal était de diviser la liste en sous-listes et de supprimer les 5 premier et dernier éléments, et après cela pour combinez-les dans une liste. Merci encore
@AlexDavies vous voulez dire [list (group) [2: -2] for group in mit.consecutive_groups (index_to_remove)]
??
@ andy_91, oui, c'est ce que je voulais dire. le seul problème en l'utilisant est que cela créera plusieurs sous-listes dans une grande liste. Par exemple: list = [[liste 1], [liste 2], [liste 3]] et j'aimerais avoir une grande liste sans minilistes à l'intérieur.
@AlexDavies list (itertools.chain.from_iterable ([list (group) [2: -2] for group in mit.consecutive_groups (index_to_remove)]))
, import itertools
première
Sans compliquer les choses, vous pouvez simplement résoudre quelque chose comme ceci:
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], [160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170]]
Test:
#Stephen's list print(list(chunk_lists_(list(range(0, 11)) + list(range(80, 91)) + list(range(160, 171)))))
sortie:
def chunk_lists_(data_): consecutive_list = [] for chunks in range(len(data_)): try: #check consecutiveness if data_[chunks + 1] - data_[chunks] == 1: #check if it's already in list if data_[chunks] not in consecutive_list: consecutive_list.append(data_[chunks]) #add last one too consecutive_list.append(data_[chunks + 1]) else: #yield here and empty list yield consecutive_list consecutive_list = [] except Exception: pass yield consecutive_list
Vous souhaitez diviser les listes sur les lacunes?
Ouais en gros. Le plus important est de diviser les indices consécutifs dans une sous-liste @StephenRauch