1
votes

Quelle est la formule pour compter le nombre de passes d'un élément de liste s'il est cyclé x fois

Given

    # if we cycled list 4 times, output would be
    output = [('a',2), ('b',1), ('c',1)]

    # if we cycled list 7 times, output would be
    output = [('a',3), ('b',2), ('c',2)]

Comment obtenir le nombre de fois où un élément est accédé en parcourant la liste x fois. Par exemple:

    list =['a','b','c']

Y a-t-il une formule pour cela, ou une boucle est-elle nécessaire?


3 commentaires

Indice: disons que vous faites 7 "sauts", quel est le nombre de visites pour chaque élément?


et oui, il y a une "logique" pour cela, qui ne nécessite pas de bouclage.


output = [('a', 3), ('b', 3), ('c', 1)] est faux pour 7 ... Divisez simplement le no. de fois par la longueur de la liste et regardez le quotient et le reste que vous pouvez obtenir en utilisant %


5 Réponses :


1
votes

Ce n'est peut-être pas la meilleure approche, mais vous pourriez toujours la trouver utile. L'idée est de trouver la liste étendue puis d'utiliser Counter pour obtenir la fréquence d'occurrence

from collections import Counter

n = 7
listt = ['a','b','c']

a = n%len(listt) 
b = int(n/len(listt))

listt = listt*b + listt[0:a]
result = [(i, j) for i,j in Counter(listt).items()]
print (result)
# [('a', 3), ('b', 2), ('c', 2)]


0 commentaires

1
votes

Vous pouvez simplement diviser la longueur de la liste par le nombre de boucles, et ajouter 1 pour les éléments dont l'index est inférieur au reste:

def nb_accesses(sequence, loops):
    length = len(sequence)
    out = [(value, loops // length + (index < loops % length))
            for index, value in enumerate(sequence)]
    return out

sequence = ['a', 'b', 'c']

print(nb_accesses(sequence, loops=0))
# [('a', 0), ('b', 0), ('c', 0)]

print(nb_accesses(sequence, loops=3))
# [('a', 1), ('b', 1), ('c', 1)]

print(nb_accesses(sequence, loops=5))
# [('a', 2), ('b', 2), ('c', 1)]

index prend la valeur 0 (False) ou 1 (True).


0 commentaires

2
votes

Vous pouvez calculer cela partiellement, mais une boucle est nécessaire à un moment donné pour cette approche. Utilisez la division par étage pour trouver le nombre de passes complètes effectuées, puis incrémentez le reste de 1 (en commençant par la gauche) pour le reste - passes incomplètes:

(x//y, x%y)
# floor division, modulus

Remarque sur divmod :

divmod(x, y)

... renvoie ...

data = ['a', 'b', 'c']
cycles = 7
complete_passes, remainder = divmod(cycles, len(data))
passes = {i: complete_passes for i in data}
for key in data[:remainder]:
    passes[key] += 1


0 commentaires

1
votes

Le nombre de fois où nous visitons le k -ème élément dans une liste avec n éléments et v visites est ⌈ (vk) / n⌉, qui équivaut à ⌊ (v-k + n-1) / n⌋. Après tout, nous effectuons des visites v , ce qui signifie que chaque élément a au moins ⌊v / n-1⌋ visites. Le dernier "round" distribue les éléments v - ⌊v / n-1⌋ restants, et les premiers v - ⌊v / n-1⌋ éléments "récupèrent" une visite .

Nous pouvons générer une telle liste en temps linéaire avec:

>>> visit_count('abcde', 1_234_567_890_123_456)
[('a', 246913578024692), ('b', 246913578024691), ('c', 246913578024691), ('d', 246913578024691), ('e', 246913578024691)]

Par exemple:

>>> visit_count('abc', 7)
[('a', 3), ('b', 2), ('c', 2)]
>>> visit_count('abc', 8)
[('a', 3), ('b', 3), ('c', 2)]
>>> visit_count('abc', 9)
[('a', 3), ('b', 3), ('c', 3)]
>>> visit_count('abc', 10)
[('a', 4), ('b', 3), ('c', 3)]

Puisque cela fonctionne dans la longueur de la liste, et non dans le nombre de visites, cela signifie que nous pouvons résoudre ce problème pour des listes raisonnables et un nombre énorme de visites. Par exemple:

def visit_count(data, v):
    n = len(data)
    return [(x, (v-i+n-1)//n) for i, x in enumerate(data)]

Faire la comptabilité pour 1'234'567'890'123'456 visites individuellement entraînerait la fonction de prendre des années pour obtenir le résultat. Mais comme le nombre d'éléments (ici 5) est limité, cela ne prend que quelques microsecondes.


1 commentaires

(v-i + n-1) // n est ce que je cherchais. Merci Monsieur !



0
votes

XXX

iterable = (it.islice(it.cycle(lst),  n)
[(k, v) for k, v in ct.Counter(iterable).items()]
# [('a', 3), ('b', 2), ('c', 2)]


0 commentaires