je la liste suivante de tuples dans Python3.x, chaque tuple se compose de deux entiers au format (start, end)
:Trouver tuples qui se chevauchent dans une liste Python et les mélangeant
list_tuple = [(20, 35), (125, 145), (156, 178), (211, 233), (220, 321),
(227, 234), (230, 231), (472, 498), (4765, 8971)]
## list already sorted except for last tuple
Ce des tuples comme des intervalles le long d'une ligne réelle, par exemple (1,10)
est un intervalle de 1 à 10.
Il y a trois façons de trier ce tuple, soit par le premier élément seul, par le second élément seul, soit par le premier et le second élément.
Tri par le premier élément seul:
sorted_by_first = sorted(list_tuple, key=lambda element: (element[0])) ## (first_element, second_element)
qui délivre en sortie
print(sorted_by_first)
[(20, 35), (125, 145), (156, 178), (211, 233), (220, 321), (227, 234), (230, 231), (472, 498), (4765, 8971)]
et pour le tri sur la base du deuxième élément:
sorted_by_second = sorted(list_tuple, key=lambda element: (element[1]))
qui délivre en sortie
print(sorted_by_second)
[(20, 35), (125, 145), (156, 178), (230, 231), (211, 233), (227, 234), (220, 321), (472, 498), (4765, 8971)]
et pour les deux:
sorted_by_both = sorted(list_tuple, key=lambda element: (element[0], element[1]))
qui délivre en sortie
print(sorted_by_both)
[(20, 35), (125, 145), (156, 178), (211, 233), (220, 321), (227, 234), (230, 231), (472, 498), (4765, 8971), ...]
Notez que chacune de ces sorties sont classées dans un ordre différent. Les tuples qui diffèrent par ordre sont des "intervalles de chevauchement", par ex. devrait (227, 234)
être placé avant ou après (230, 231)
, que ces intervalles se chevauchent.
Mon but est de créer une fonction qui (1) recherche la sortie triée pour les "intervalles de chevauchement" et (2) puis les permute aléatoirement entre eux.
Je peux penser à une fonction qui sort tous les tuples qui chevauchent un tuple donné, par ex.
def find_overlaps(input_tuple_list, search_interval):
results = []
for tup in input_tuple_list:
if ((tup[0] >= search_interval[0] and tup[0] <= search_interval[1]) or (tup[1] >= search_interval[0] and tup[1] <= search_interval[1])):
results.append(tup)
return results
qui fonctionne comme suit
foo = (130, 150)
overlapping_foo = find_overlaps(list_tuple, foo)
print(overlapping_foo)
[(125, 145)]
Cependant, afin d'atteindre l'objectif (1), je dois écrire une fonction qui trouve toutes les lignes qui se chevauchent dans list_tuple
. Ce que j'ai essayé: J'ai d'abord pensé que je pouvais rechercher le tuple original avec lui-même, par ex.
total_overlaps = []
for tupp in list_tuple:
total_overlaps.append(find_overlaps(list_tuple, tupp))
Ceci est évidemment faux, car la sortie est le tuple d'origine lui-même.
Le plus gros problème avec est que je ne vois pas comment exécuter le but (2). Je dois seulement mélanger/réorganiser les tuples qui se chevauchent.Disons que j'avais une liste de tuples qui se chevauchent résultat (1):
overlap_list = [(211, 233), (220, 321), (227, 234), (230, 231), (6491, 7000), (6800, 7200)]
La compréhension de la liste suivante échoue
from random import shuffle
reordered = [shuffle(tupp) for tupp in overlap_list]
donnant
TypeError: 'tuple' object does not support item assignment
Il est également important que je ne mélangez pas (6491, 7000)
avec (211, 233)
, car ceux-ci ne sont pas liés.
Comment trouver les intervalles de chevauchement dans la liste des tuples, puis mélanger individuellement ces tuples qui se chevauchent.
Je ne suis pas sûr, mais quelque chose ne fonctionne pas vraiment: https://repl.it/JBex/0 –
Vous ne pouvez pas 'random.shuffle()' un tuple parce que les tuples sont immuables, mais vous pouvez 'random.sample (tupp, k = len (tupp))' qui crée un nouvel objet. – AChampion
Note, 'trié_par_both = trié (list_tuple, clé = élément lambda: (élément [0], élément [1]))' est * exactement équivalent à 'trié (list_tuple)', tant qu'il y a exactement 2 éléments dans chaque tuple. –