代码之家  ›  专栏  ›  技术社区  ›  Jack Arnestad

从列表中随机选择值,但有字符长度限制

  •  8
  • Jack Arnestad  · 技术社区  · 6 年前

    我有两个字符串列表,如下所示:

    test1 = ["abc", "abcdef", "abcedfhi"]
    
    test2 = ["The", "silver", "proposes", "the", "blushing", "number", "burst", "explores", "the", "fast", "iron", "impossible"]
    

    第二个列表较长,所以我想通过随机抽样将其缩小到第一个列表的长度。

    def downsample(data):
        min_len = min(len(x) for x in data)
        return [random.sample(x, min_len) for x in data]
    
    downsample([list1, list2])
    

    但是,我想添加一个限制,从第二个列表中选择的单词必须与第一个列表的长度分布相匹配。因此,对于随机选择的第一个单词,它的长度必须与较短列表中的第一个单词的长度相同。这里的问题是也不允许更换。

    如何从中随机选择n个(较短列表的长度)元素 test2 它与 test1 ? 谢谢, 杰克

    2 回复  |  直到 6 年前
        1
  •  7
  •   user3483203    6 年前

    安装程序

    from collections import defaultdict
    import random
    dct = defaultdict(list)
    l1 = ["abc", "abcdef", "abcedfhi"]
    l2 = ["The", "silver", "proposes", "the", "blushing", "number", "burst", "explores", "the", "fast", "iron", "impossible"]
    

    首先,使用 collections.defaultdict 要创建关键字为单词长度的词典,请执行以下操作:

    for word in l2:
      dct[len(word)].append(word)
    
    # Result
    defaultdict(<class 'list'>, {3: ['The', 'the', 'the'], 6: ['silver', 'number'], 8: ['proposes', 'blushing', 'explores'], 5: ['burst'], 4: ['fast', 'iron'], 10: ['impossible']})
    

    然后你可以使用一个简单的列表理解和 random.choice 选择与第一个列表中每个元素的长度匹配的随机单词。如果字长是 在你的字典里,填上 -1 :

    final = [random.choice(dct.get(len(w), [-1])) for w in l1]
    
    # Output
    ['The', 'silver', 'blushing']
    

    根据明确的要求进行编辑
    下面是一种方法,它满足了在列表2中不存在重复项时不允许重复项的要求:

    for word in l2:
        dct[len(word)].append(word)
    
    for k in dct:
        random.shuffle(dct[k])
    
    final = [dct[len(w)].pop() for w in l1]
    # ['The', 'silver', 'proposes']
    

    这种方法将提高 IndexError 如果第二个列表中没有足够的单词来完成分发。

        2
  •  1
  •   niraj    6 年前

    一种方法可能是创造 list 项目长度 test1 . 然后,使用它创建包含 这些长度的子列表 test2 . 最后从列表中随机弹出(如下 similar answer ),以便在为样本选择后移除该项。

    from random import randrange
    
    test1 = ["abc", "abcdef", "abcedfhi"]
    test2 = ["The", "silver", "proposes", "the", "blushing", "number", "burst", "explores", "the", "fast", "iron", "impossible"]
    
    sizes = [len(i) for i in test1]
    # results: [3, 6, 8]
    
    sublists = [[item for item in test2 if len(item) == i] for i in sizes ]
    # results for sublists: [['The', 'the', 'the'], ['silver', 'number'], ['proposes', 'blushing', 'explores']]
    
    # randomly pop from the list for samples 
    samples = [i.pop(randrange(len(i)))  for i in sublists]
    
    print('Samples: ',samples)
    

    结果:

    Samples:  ['the', 'number', 'blushing']