【问题标题】:What is the formula to count number of passes of a list items if cycled x times如果循环 x 次,计算列表项通过次数的公式是什么
【发布时间】:2019-01-30 20:35:48
【问题描述】:

给定

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

如何在循环列表 x 次时获取项目被访问的次数。例如:

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

是否有一个公式,或者循环是必要的?

【问题讨论】:

  • 提示:假设你做了 7 个“跳”,每个项目的访问次数是多少?
  • 是的,这有一个“逻辑”,不需要循环。
  • output = [('a',3), ('b',3), ('c',1)] 对 7 来说是错误的...只需除以数字即可。按列表长度计算的次数,并查看商和余数,您可以使用%

标签: python algorithm math itertools discrete-mathematics


【解决方案1】:

您可以部分计算此值,但这种方法有时需要一个循环。使用地板除法找出完成了多少次通过,然后将剩余的通过 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

注意divmod

divmod(x, y)

...返回...

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

【讨论】:

    【解决方案2】:

    我们访问包含 n 个项目的列表中第 k 个项目的次数,并且 v 次访问是⌈(v-k) /n⌉,等价于⌊(v-k+n-1)/n⌋。毕竟我们进行了 v 次访问,这意味着每个项目至少有 ⌊v/n-1⌋ 次访问。最后“一轮”分发剩余的v - ⌊v/n-1⌋,第一个v - ⌊v/n-1⌋项“检索”一次访问.

    我们可以在线性时间内生成这样的列表:

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

    例如:

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

    由于这在列表的长度上运行,而不是在访问次数上,这意味着我们可以针对合理的列表和大量的访问次数来解决这个问题。例如:

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

    单独记账 1'234'567'890'123'456 次访问会导致函数需要很长时间才能获得结果。但是由于元素的数量(这里是 5 个)是有限的,所以只需要几微秒。

    【讨论】:

    • (v-i+n-1)//n 是我要找的。谢谢楼主!
    【解决方案3】:

    这可能不是最好的方法,但您可能仍会发现它很有用。思路是找到扩展列表,然后用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)]
    

    【讨论】:

      【解决方案4】:

      你可以简单地将列表的长度除以循环的次数,并为索引小于余数的元素加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 &lt; loops % length 计算结果为 0(假)或 1(真)。

      【讨论】:

        【解决方案5】:

        给定

        import itertools as it
        import collections as ct
        
        
        lst = list("abc")
        n = 7
        

        代码

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

        【讨论】:

          猜你喜欢
          • 2016-03-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-09
          • 2015-04-12
          • 2011-11-08
          相关资源
          最近更新 更多