简体   繁体   English

如果循环x次,计算列表项的通过次数的公式是什么

[英]What is the formula to count number of passes of a list items if cycled x times

Given 给定

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

How to get number of times an item gets accessed when cycling the list x times. 如何在循环列表x次时获取项目被访问的次数。 For example: 例如:

    # 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)]

Is there a formula for this, or a loop is necessary? 是否有一个公式,或者需要循环?

You could calculate this partially, but a loop is needed at some point for this approach. 您可以对此进行部分计算,但是此方法有时需要一个循环。 Use floor division to find how many complete passes are made, then increment the rest by 1 (starting from the left) for the remainder - incomplete passes: 使用楼层划分来查找完成的通行证的数量,然后将剩余的剩余通行证增加1(从左开始)-不完整的通行证:

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

Note on divmod : 注意divmod

divmod(x, y)

...returns... ...返回...

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

This might not be the best approach but you might still find it useful. 这可能不是最好的方法,但您可能仍然发现它很有用。 The idea is to find have the extended list and then use Counter to get the occurrence frequency 想法是找到具有扩展的列表,然后使用Counter获得发生频率

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)]

You can simply divide the length of the list by the number of loops, and add 1 for the elements whose index is less than the remainder: 您可以简单地将列表的长度除以循环数,然后为索引小于其余数的元素加1:

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 < loops % length evaluates to 0 (False) or 1 (True). index < loops % length计算为0(假)或1(真)。

The number of times we visit the k -th item in a list with n items, and v visits is ⌈(vk)/n⌉, which is equivalent to ⌊(v-k+n-1)/n⌋. 我们在具有n个项目的列表中访问第k个项目的次数,而v次访问是⌈(vk)/n⌉,它等于⌊(v-k + n-1)/n⌋。 After all we make v visits, so that means each item has at least ⌊v/n-1⌋ visits. 毕竟,我们进行了v次访问,因此这意味着每个项目至少有⌊v/ n-1次访问。 The last "round" distributes the remaining v - ⌊v/n-1⌋ , and the first v - ⌊v/n-1⌋ items "retrieve" a visit. 最后一个“回合”分发剩余的v-⌊v/n-1⌋ ,而第一个v-⌊v/n-1⌋项“检索”访问。

We can generate such list in linear time with: 我们可以在线性时间内生成这样的列表:

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

For example: 例如:

>>> 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)]

Since this runs in the length of the list, and not in the number of visits, it means that we can solve this problem for reasonable lists, and a huge number of visits. 由于这取决于列表的长度,而不是访问次数,因此这意味着我们可以通过合理的列表和大量访问来解决此问题。 For example: 例如:

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

Doing the bookkeeping for 1'234'567'890'123'456 visits individually would result in the function taking ages to obtain the result. 单独进行1'234'567'890'123'456访问的簿记将导致该函数花很多时间才能获得结果。 But since the number of elements (here 5) is limited, it takes only a few microseconds. 但是由于元素数(此处为5)是有限的,因此仅需几微秒。

Given 给定

import itertools as it
import collections as ct


lst = list("abc")
n = 7

Code

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM