在列表中生成两个独特但随机的元素

3
我需要生成一个独特元素的列表。
parties = ['Party A', 'Party B']

我尝试过这个。
def party_generator(size=1, chars=string.ascii_uppercase):
    parties = []
    for y in range(2):
        party = ''.join(random.choice(chars) for x in range(size))
        parties.append(''.join(['Party ', party]))
    return parties

但我担心我的代码可能会生成重复数据。
party_generator()
['Party S', 'Party S']

如何生成一个只包含唯一元素的列表?

1个回答

2
使用一个 set 来追踪是否之前已经生成过相同的随机字符串:
def party_generator(size=1, chars=string.ascii_uppercase):
    parties = []
    seen = set()
    while len(parties) < 2:
        party = ''.join(random.choice(chars) for x in range(size))
        if party in seen:
            continue
        seen.add(party)
        parties.append('Party {}'.format(party))
    return parties

这将一直生成随机字符串,直到你有2个独特的值。

在这里你不能轻易使用random.sample(),因为它需要一个固定的选择集才能进行抽样,而你正在生成长度可变的名称。但是可以构建一个对象来模拟序列(给它提供__len____getattr__方法),并从你可以创建的所有可能单词中生成指定长度size的单词,给定了chars变量:

class CharacterRange(object):
    def __init__(self, chars, size):
        self.chars, self.size = chars, size

    def __len__(self):
        return len(self.chars) ** self.size

    def __getitem__(self, item):
        if item < 0:
            item = len(self) + item
        if not 0 <= item <= len(self):
            raise IndexError('Index out of range')

        result = []
        for i in range(self.size):
            item, index = divmod(item, len(self.chars))
            result.append(self.chars[index])
        return ''.join(result[::-1])

示例:

>>> uppercase_len1 = CharacterRange(string.uppercase, 1)
>>> len(uppercase_len1)
26
>>> uppercase_len5[0]
'A'
>>> uppercase_len5[-1]
'Z'
>>> uppercase_len1[10]
'K'
>>> uppercase_len1[24]
'Y'
>>> uppercase_len5 = CharacterRange(string.uppercase, 5)
>>> len(uppercase_len5)
11881376
>>> uppercase_len5[0]
'AAAAA'
>>> uppercase_len5[-1]
'ZZZZZ'
>>> uppercase_len5[1024]
'AABNK'
>>> uppercase_len5[1355453]
'CZDCV'

你可以将 this对象传递给 random.sample()
>>> import random
>>> random.sample(uppercase_len5, 5)
['CUSQB', 'UUUWM', 'MKOFI', 'MYROU', 'AHRWA']

在线性时间和恒定内存中生成长度为K的N个单词。

你可以简化你的代码为:

def party_generator(size=1, chars=string.ascii_uppercase):
    return ['Party {}'.format(party) for party in random.sample(CharacterRange(chars, size))]

不过,我认为对于只有两个随机词来说,这样做有点过头了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接