-1
votes

Comment vérifier si les éléments consécutifs du tableau sont régulièrement espacés?

Par exemple:

if len(set([arr[x] - arr[x - 1] for x in range(1, len(arr))])) > 1:
    print('not equally spaced')

Je suppose que je pourrais faire quelque chose comme:

[1,2,3,4,5,6] -> True
[1,2,3,5,6] -> False

Je me demandais s'il y avait un meilleur moyen?


10 commentaires

Mieux veut dire quoi exactement?


Faites la différence entre les deux premiers éléments. Ensuite, parcourez le tableau, en vous arrêtant si une paire a une différence différente.


@StephenRauch Plus efficace en termes de calcul. Idéalement. Je pense que la réponse de Barmar est probablement ce que je cherchais.


Une chose est que vous n'avez pas besoin de construire une liste. Retirez simplement les crochets.


@learningthemachine, puis utilisez numpy.


@StephenRaunch Que faire si le tableau contient 10 millions d'éléments et que les deux premières paires sont espacées différemment?


@scott, et si elles sont toutes espacées de la même manière?


@StephenRauch. Exactement. Cela dépend de facteurs de confusion, donc au lieu de "alors utilisez numpy" :: "utilisez peut-être numpy, cela dépend"


@Scott Pour mes besoins, ce n'est qu'une fonction oui ou non, donc cela n'aurait pas vraiment d'importance. Le résultat final de la comparaison d'une valeur aberrante à la norme ou de la norme à une valeur aberrante est le même.


@learningthemachine, c'est une différence de performance.


5 Réponses :


1
votes

essayez ceci, pour qu'une liste soit consécutive

  • la différence entre le dernier élément et le premier élément plus 1 doit être égale à la longueur de la liste
  • la longueur de la liste vs la longueur de l'ensemble doit correspondre pour exclure les entrées répétées
  • La liste doit être triée pour que cela fonctionne.

code

def check_evenly_space(input_list):
    if len(input_list)==1:
        return False
    space = input_list[1] - input_list[0]
    if space==0:
        return False
    return list(range(input_list[0], input_list[-1] + space, space)) == input_list

check_evenly_space([1,2,3,4,5,6]) # True
check_evenly_space([1,2,3,5,6])   # False
check_evenly_space([2,4,6,8,10])  # True
check_evenly_space([2,4,6,7,10])  # False

comme la mention du commentaire, le code ci-dessus ne fonctionne que pour l'espacement de 1 unité et nous pourrions omettre la partie de la liste de tri si la liste d'entrée est déjà triée

pour le rendre générique pour n'importe quelle unité spatiale, nous pourrions essayer le code ci-dessous. Il crée d'abord la liste d'espace uniformément idéale basée sur l'unité d'espace input_list, puis diffère par rapport à input_list. Le code ci-dessous suppose que input_list est déjà trié

def check_consecutive(input_list):
    input_list = sorted(input_list)
    return (input_list[-1] - input_list[0]) + 1 == len(input_list) and (len(input_list) == len(set(input_list))

check_consecutive([1,2,3,4,5,6]) # True
check_consecutive([1,2,3,5,6])   # False


4 commentaires

"régulièrement espacés", mais cet espace n'est pas nécessairement une unité. Je pense que vous pouvez résoudre ce problème en multipliant la différence des deux premiers éléments quelque part.


Je ne pense pas. Si les éléments de la liste ne sont pas strictement adjacents, ils peuvent présenter des espaces qui empêchent les comparaisons de taille. Par exemple, [1, 2, 5] serait accepté car le code ne peut pas faire la différence entre lui et [1, 3, 5] . Et le tri de la liste est un peu problématique, car vous devez de toute façon vous assurer que les éléments sont en ordre. [3, 5, 1] n'est pas valide!


Cela générera une erreur pour les listes comme [3] ou [5, 5, 9] .


@ kaya3, ajouté corrigé pour cela



-1
votes

Vous pouvez essayer ceci

def ContiguousElem(arr):
    ss = set() 
    for i in arr: ss.add(i)
    count = 1
    curr = arr[0] - 1
    while curr in ss:
        count += 1
        curr -= 1
    curr = arr[0] + 1

    while curr in ss: 
        count += 1
        curr += 1
    return (count == len(ss)) 
arr1 = [1,2,3,4,5,6]
arr2 = [1,2,3,5,6]
if ContiguousElem(arr1): print("Yes") 
else: print("No") 
if ContiguousElem(arr2): print("Yes") 
else: print("No") 

o/p : Yes
      No


3 commentaires

Pourquoi convertissez-vous le tableau en un ensemble?


Cet algorithme n'est pas simple, vous devez donc expliquer comment il fonctionne.


Ici, j'essaie juste de pousser les éléments de 'arr []' dans une table / ensemble de hachage et de choisir le premier élément et de continuer à incrémenter sa valeur de 1 jusqu'à ce que vous trouviez une valeur non présente dans la table de hachage. De même pour les autres éléments. nombre d'éléments (obtenus par ce processus) qui sont présents dans la table de hachage. Si le nombre est égal à la taille de hachage, imprimez «Oui» sinon «Non». De cette façon, nous pouvons réduire la complexité temporelle à O (n).



1
votes

Voici ce que j'ai fini par faire ...

def same_dist_elems(arr):
    diff = arr[1] - arr[0]
    for x in range(1, len(arr) - 1):
        if arr[x + 1] - arr[x] != diff:
            return False
    return True

Crédits à Barmar mais il n'a mis qu'un commentaire pas une réponse


2 commentaires

C'est la solution la plus simple, mais vous devez gérer les listes de moins de 2 comme cas particulier. Sinon, diff = arr[1] - arr[0] lèvera une IndexError.


J'essaye avec les valeurs a, b, c comme suit mais je n'obtiens pas de sortie def same_dist_elems (a, b, c): arr = (a, b, c) diff = arr [1] - arr [ 0] for x in range (1, len (arr) - 1): if arr [x + 1] - arr [x]! = Diff: return False return True # code de test same_dist_elems (2, 4, 6)



0
votes

Une solution simple consiste à comparer la liste avec une plage. Pour enregistrer la conversion de la plage en liste, nous pouvons utiliser zip et all . Ce n'est pas la solution la plus efficace possible, mais c'est toujours le temps O ( n ) et l'espace auxiliaire O (1).

def list_is_evenly_spaced(lst):
    # special case: a list with 0, 1 or 2 elements is evenly spaced
    if len(lst) <= 2:
        return True

    first = lst[0]
    gap = lst[1] - first
    # special case: a constant list is evenly spaced
    if gap == 0:
        return all(x == first for x in lst)

    # general case: an evenly spaced list equals a range
    r = range(first, first + gap*len(lst), gap)
    return all(x == y for x,y in zip(lst, r))

Explication des cas particuliers, qui doivent être traités séparément:

  • Une liste de 0, 1 ou 2 éléments est toujours régulièrement espacée. Pour être espacés de manière inégale, il doit y avoir deux espaces différents, impliquant au moins trois éléments.
  • Une liste de constantes est toujours régulièrement espacée, car chaque espace est égal à 0. Cependant, il n'est pas valide de construire une plage avec un espace de 0.


0 commentaires

1
votes

Vous pouvez simplement vérifier si les différences sont toutes les mêmes (en utilisant numpy.diff):

import numpy as np
a = np.array([1,2,3,4,5,6])
b = np.array([1,2,3,5,6])

all(np.diff(a)==np.diff(a)[0])  # --> True
all(np.diff(b)==np.diff(b)[0])  # --> False


0 commentaires