【问题标题】:How can I create 2 random lists based on 1 list?如何根据 1 个列表创建 2 个随机列表?
【发布时间】:2021-12-28 12:34:00
【问题描述】:

我有一个 global_list:[1,7,23,72,7,83,60] 我需要从这个列表中创建 2 个随机列表(示例):

  • list_1: [7, 7, 23, 83, 72]
  • list_2: [1, 60]

我的实际工作代码是:

import random
import copy

def get_2_random_list(global_list, repartition):
    list_1, list_2 = [], copy.copy(global_list)
    list_1_len = round(len(list_2)*repartition)
    print("nbr of element in list_1:",list_1_len)
    for _ in range(list_1_len):
        index = random.randint(1,len(list_2)-1)
        list_1.append(list_2[index])
        del list_2[index]
    return list_1, list_2


global_list = [1,7,23,72,7,83,60]
list_1,list_2 = get_2_random_list(global_list,0.7)
print("list_1:", list_1)
print("list_2:", list_2)
print("global_list:", global_list)

我觉得它可以优化。 (也许我在random 库上搜索得不够多)在效率方面(我正在处理数百万个元素)和密度方面(我希望该函数有 1 或 2 行代码) .

【问题讨论】:

    标签: python list optimization random


    【解决方案1】:
    def get_2_random_list(global_list, repartition):
        g_list = list(global_list)
        random.shuffle(g_list)
        split_point = round(len(g_list)*repartition)
        
        return g_list[:split_point], g_list[split_point:]
    

    【讨论】:

      【解决方案2】:

      尝试使用 NumPy:

      l = [1,7,23,72,7,83,60]
      l2 = l.copy()
      # randomly select a number based on the len of the list
      split_num = np.random.choice(len(l), 1)
      # create a new list by using random choice without replacement
      l1 = list(np.random.choice(l, split_num, replace=False))
      # remove the numbers in l1 from the original list
      [l2.remove(x) for x in l1]
      # print your two new lists
      print(l1)
      print(l2)
      print(l)
      
      [60, 83, 23, 72]
      [1, 7, 7]
      [1, 7, 23, 72, 7, 83, 60]
      

      【讨论】:

        【解决方案3】:

        也许我在随机库上搜索的不够多

        如果你没有找到random.sample,那你肯定是搜索不够

        def get_2_random_list(global_list, repartition):
            list_1_len = int(round(len(global_list)*repartition))
            list1 = random.sample(global_list, list_1_len)
            set1 = set(list1)
            list2 = [element for element in global_list if element not in set1]
            return list1, list2
        

        编辑:如果您的列表项不是唯一的,这将是生成 list2 的更好方法:

        def get_2_random_list(global_list, repartition):
            global_len = len(global_list)
            list_1_len = int(round(global_len*repartition))
            list1_indices = random.sample(range(global_len), list_1_len)
            list1 = [global_list[idx] for idx in list1_indices]
            set1 = set(list1_indices)
            list2 = [element for idx, element in enumerate(global_list)
                     if idx not in set1]
            return list1, list2
        

        附录:如果您对list2中元素的顺序不感兴趣,使用random.shuffle会更快。

        def get_2_random_list(global_list, repartition):
            list_1_len = int(round(len(global_list)*repartition))
            lstcopy = list(global_list)
            random.shuffle(lstcopy)
            list1 = lstcopy[:list_1_len]
            list2 = lstcopy[list_1_len:]
            return list1, list2
        

        【讨论】:

          【解决方案4】:

          我会使用随机库中的示例方法。它类似于选择方法,但不允许重复。最后,我将所有不在 list_1 中的项目添加到 list_2。

          def get_2_random_list(global_list, repartition):
              list_1_len = round(len(global_list) * repartition)
          
              list_1 = random.sample(global_list, list_1_len)
              list_2 = [i for i in global_list if i not in (list_1)]
          
              return list_1, list_2
          

          【讨论】:

            【解决方案5】:

            如果您的重新分区是概率(而不是项目的一部分),您需要将其用作阈值,以将项目随机放置在第一个或第二个列表中:

            import random
            
            L = [1,7,23,72,7,83,60]
            
            repartition = 0.7 # as a probability
            L1,L2 = [],[]
            for n in L:
                (L1,L2)[random.random()>repartition].append(n)
                
            print(L1)  # [23, 72, 60]
            print(L2)  # [1, 7, 7, 83]
            

            这意味着项目有 70% 的机会被放置在第一个列表中,并且有 30% 的机会进入第二个列表。对于短名单,这通常甚至不会接近 70/30 的项目比例。

            如果你的 repartition 用 item 的数量来表示一个比例,你可以使用 random.sample 来避免修改原始列表:

            from random import sample
            
            L = [1,7,23,72,7,83,60]
            
            repartition = 0.7 # as a proportion of items
            
            L1,L2 = (lambda R,p:(R[:p],R[p:]))(sample(L,len(L)),round(repartition*len(L)))
                
            print(L1) # [7, 83, 7, 72, 60]
            print(L2) # [23, 1]
            

            【讨论】:

              【解决方案6】:

              NumPy 有一个函数 shuffle 可能会有所帮助:

              arr = np.array([1,7,23,72,7,83,60])
              np.random.shuffle(arr)
              p = 5
              a1 = arr[:p]
              a2 = arr[p:]
              print(a1)
              print(a2)
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-07-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-09-28
                相关资源
                最近更新 更多