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?
5 Réponses :
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)]
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
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
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.
(v-i + n-1) // n est ce que je cherchais. Merci Monsieur !
XXX
iterable = (it.islice(it.cycle(lst), n) [(k, v) for k, v in ct.Counter(iterable).items()] # [('a', 3), ('b', 2), ('c', 2)]
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%