【问题标题】:Finding first time value occurs in an array when you don't know what it is当您不知道它是什么时,在数组中查找第一次值
【发布时间】:2019-03-19 22:45:37
【问题描述】:

我有一个非常长的数组(超过 200 万个值),其中包含重复值。它看起来像这样:

array  = [1,1,1,1,......,2,2,2.....3,3,3.....]

有一堆不同的值。我想为每组点创建单独的数组。 IE:一个数组,一个数组,以此类推。所以看起来像:

array1 = [1,1,1,1...]
array2 = [2,2,2,2.....]
array3 = [3,3,3,3....]
.
.
.
.


None of the values occur an equal amount of time however, and I don't know how many times each value occurs.  Any advice?

【问题讨论】:

    标签: python arrays


    【解决方案1】:

    假设重复的值被组合在一起(否则你只需要sort列表),你可以使用itertools.groupby创建一个嵌套列表(而不是为每个不同的值创建一个新列表):

    from itertools import groupby
    array  = [1,1,1,1,2,2,2,3,3]
    
    [list(v) for k,v in groupby(array)]
    [[1, 1, 1, 1], [2, 2, 2], [3, 3]]
    

    请注意,这比创建n 动态创建的新列表更方便,例如this 帖子中所示,因为您不知道将创建多少个列表,您必须参考每个列表按名称列出,而不是简单地索引一个嵌套列表

    【讨论】:

    • 太棒了,有没有办法查看当时有多少组? len() 会告诉你长度吗?
    • 是的,只需选择@wilada 列表中的len。如果有帮助,请不要忘记您可以投票/接受:)
    【解决方案2】:

    您可以使用bisect.bisect_left 查找每个元素第一次出现的索引。这仅在列表已排序时才有效:

    from bisect import bisect_left
    
    def count_values(l, values=None):
        if values is None:
            values = range(1, l[-1]+1)  # Default assume list is [1..n]
        counts = {}
        consumed = 0
        val_iter = iter(values)
        curr_value = next(val_iter)
        next_value = next(val_iter)
        while True:
            ind = bisect_left(l, next_value, consumed)
            counts[curr_value] = ind - consumed
            consumed = ind
            try:
                curr_value, next_value = next_value, next(val_iter)
            except StopIteration:
                break
        counts[next_value] = len(l) - consumed
        return counts
    
    l = [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3]
    
    print(count_values(l))
    # {1: 9, 2: 8, 3: 7}
    

    这避免了扫描整个列表,将其换成对每个值的二进制搜索。期望在每个元素非常多的情况下性能更高,而在每个元素很少的情况下性能较低。

    【讨论】:

      【解决方案3】:

      好吧,创建所有这些数组似乎既浪费又多余,每个数组都只存储重复值。

      您可能只想创建一个包含唯一值及其各自计数的字典。

      从这本字典中,您可以随时轻松地有选择地创建任何单独的数组,以及您想要的任何特定数组。

      要创建这样的字典,您可以使用:

      from collections import Counter
      
      my_counts_dict = Counter(my_array)
      

      一旦你有了这个字典,你就可以得到23的数量,例如my_counts_dict[23]

      如果返回 200,您可以使用以下命令创建 200 23 列表:

      my_list23 = [23]*200
      

      【讨论】:

        【解决方案4】:

        ****使用此代码****

        <?php 
        $arrayName =  array(2,2,5,1,1,1,2,3,3,3,4,5,4,5,4,6,6,6,7,8,9,7,8,9,7,8,9);
        $arr = array();
        foreach ($arrayName as $value) {
         $arr[$value][] = $value;
         }
          sort($arr);
         print_r($arr);
         ?>
        

        【讨论】:

          【解决方案5】:

          没有辅助函数的解决方案:

          array  = [1,1,2,2,2,3,4]
          
          result = [[array[0]]]
          for i in array[1:]:
              if i == result[-1][-1]:
                  result[-1].append(i)
              else:
                  result.append([i])
          
          print(result)
          # [[1, 1], [2, 2, 2], [3], [4]]
          

          【讨论】:

            猜你喜欢
            • 2020-05-28
            • 1970-01-01
            • 2017-09-30
            • 1970-01-01
            • 2021-07-14
            • 1970-01-01
            • 2010-10-16
            • 1970-01-01
            • 2017-09-29
            相关资源
            最近更新 更多