社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在下一个子列表中添加新元素,这取决于python是否添加了新元素(还涉及字典问题)

Arnoldo Oliva • 3 年前 • 1244 次点击  

Stackoverflow社区:

我试图创建一个带有循环的子列表,该循环基于对另一个列表的值的随机抽样;每个子列表都有一个限制,即不能有一个重复项或一个已经添加到先前子列表中的值。

比如说,我有一个主要列表:

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

#I get:
[[1,13],[4,1],[8,13]]

#I WANT:
[[1,13],[4,9],[8,14]]          #(no duplicates when checking previous sublists)

我认为它会起作用的真正代码如下(作为草稿):

matrixvals=list(matrix.index.values)  #list where values are obtained
lists=[[]for e in range(0,3)]         #list of sublists that I want to feed
vls=[]                                #stores the values that have been added to prevent adding them again
for e in lists:                       #initiate main loop
    for i in range(0,5):              #each sublist will contain 5 different random samples
        x=random.sample(matrixvals,1) #it doesn't matter if the samples are 1 or 2
        if any(x) not in vls:         #if the sample isn't in the evaluation list
            vls.extend(x)
            e.append(x)
        else:             #if it IS, then do a sample but without those already added values (line below)
            x=random.sample([matrixvals[:].remove(x) for x in vls],1)
            vls.extend(x)
            e.append(x)

        
print(lists)
print(vls)

当我得到以下信息时,它不起作用:

[[[25], [16], [15], [31], [17]], [[4], [2], [13], [42], [13]], [[11], [7], [13], [17], [25]]]
[25, 16, 15, 31, 17, 4, 2, 13, 42, 13, 11, 7, 13, 17, 25]

正如你所见,数字13重复了三次,我不明白为什么

我想要:

[[[25], [16], [15], [31], [17]], [[4], [2], [13], [42], [70]], [[11], [7], [100], [18], [27]]]
[25, 16, 15, 31, 17, 4, 2, 13, 42, 70, 11, 7, 100, 18, 27]   #no dups

此外,是否有一种方法可以转换样本。随机结果作为值而不是列表?(获取):

[[25,16,15,31,17]], [4, 2, 13, 42,70], [11, 7, 100, 18, 27]]

此外,实际上最终的结果不是子列表列表,实际上是一个字典(上面的代码是解决dict问题的一个尝试草案),有没有办法在dict中获得之前的方法?用我现在的代码,我得到了下一个结果:

{'1stkey': {'1stsubkey': {'list1': [41,
    40,
    22,
    28,
    26,
    14,
    41,
    15,
    40,
    33],
   'list2': [41, 40, 22, 28, 26, 14, 41, 15, 40, 33],
   'list3': [41, 40, 22, 28, 26, 14, 41, 15, 40, 33]},
  '2ndsubkey': {'list1': [21,
    7,
    31,
    12,
    8,
    22,
    27,...}

我想要的不是这个结果,而是:

 {'1stkey': {'1stsubkey': {'list1': [41,40,22],
       'list2': [28, 26, 14],
       'list3': [41, 15, 40, 33]},
      '2ndsubkey': {'list1': [21,7,31],
       'list2':[12,8,22],
       'list3':[27...,...}#and so on 

有没有办法同时解决列表和dict问题?任何帮助都将不胜感激;即使只有列表问题,我也能取得一些进展

谢谢大家

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/129290
 
1244 次点击  
文章 [ 1 ]  |  最新文章 3 年前
Paul M.
Reply   •   1 楼
Paul M.    3 年前

我知道你可能更感兴趣的是找出你的特定方法不起作用的原因。然而,如果我了解你想要的行为,我也许能提供一个替代的解决方案。在发布我的答案后,我会看看你的尝试。

random.sample 让你取样 k 来自某个应用程序的项目数 population (收集、列表等等。)如果集合中没有重复元素,则保证随机样本中没有重复:

from random import sample

pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

num_samples = 4

print(sample(pool, k=num_samples))

可能的输出:

[9, 11, 8, 7]
>>> 

不管你运行这个片段多少次,你的随机样本中永远不会有重复的元素。这是因为 随机的样品 它不会生成随机对象,只是随机选取集合中已经存在的项目。例如,当你从一副卡片中随机抽取卡片,或者抽取彩票号码时,你会采用同样的方法。

就你而言, pool 是可以从中选择样本的唯一编号池。您想要的输出似乎是一个包含三个列表的列表,其中每个子列表中有两个样本。而不是打电话 随机的样品 三次,每个子列表一次,我们应该用 k=num_sublists * num_samples_per_sublist :

from random import sample

pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

num_sublists = 3
samples_per_sublist = 2

num_samples = num_sublists * samples_per_sublist

assert num_samples <= len(pool)

print(sample(pool, k=num_samples))

可能的输出:

[14, 10, 1, 8, 6, 3]
>>> 

好的,我们有六个样本,而不是四个。还没有子列表。现在,您可以简单地将这个包含六个样本的列表拆分为三个子列表,每个子列表包含两个样本:

from random import sample

pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

num_sublists = 3
samples_per_sublist = 2

num_samples = num_sublists * samples_per_sublist

assert num_samples <= len(pool)

def pairwise(iterable):
    yield from zip(*[iter(iterable)]*samples_per_sublist)

print(list(pairwise(sample(pool, num_samples))))

可能的输出:

[(4, 11), (12, 13), (8, 15)]
>>> 

或者如果你真的想要子列表,而不是元组:

def pairwise(iterable):
    yield from map(list, zip(*[iter(iterable)]*samples_per_sublist))

编辑——刚刚意识到你其实并不想要一个列表,而是一本字典。像这样的吗?抱歉,我痴迷于发电机,这真的不容易读:

keys = ["1stkey"]
subkeys = ["1stsubkey", "2ndsubkey"]
num_lists_per_subkey = 3
num_samples_per_list = 5
num_samples = num_lists_per_subkey * num_samples_per_list

min_sample = 1
max_sample = 50

pool = list(range(min_sample, max_sample + 1))

def generate_items():

    def generate_sub_items():
        from random import sample

        samples = sample(pool, k=num_samples)

        def generate_sub_sub_items():

            def chunkwise(iterable, n=num_samples_per_list):
                yield from map(list, zip(*[iter(iterable)]*n))
        
            for list_num, chunk in enumerate(chunkwise(samples), start=1):
                key = f"list{list_num}"
                yield key, chunk

        for subkey in subkeys:
            yield subkey, dict(generate_sub_sub_items())
    
    for key in keys:
        yield key, dict(generate_sub_items())

print(dict(generate_items()))

可能的输出:

{'1stkey': {'1stsubkey': {'list1': [43, 20, 4, 27, 2], 'list2': [49, 44, 18, 8, 37], 'list3': [19, 40, 9, 17, 6]}, '2ndsubkey': {'list1': [43, 20, 4, 27, 2], 'list2': [49, 44, 18, 8, 37], 'list3': [19, 40, 9, 17, 6]}}}
>>>