我有两个数组,我想通过组合这两个数组来创建一个名称。 但是,不应重复。
除了查找名称结果值数组的递归方法之外,我还可以像返回随机名称一样返回随机名称吗?
最简单的方法是将随机生成的名称存储在列表中,并在每次创建新名称(如下所示)时查找列表。
import random
first_name = ['tony', 'adam', 'agustin', 'branden','stan']
last_name = ['smith', 'stark', 'wlliams']
full_name_dup_list = []
def generate_full_name():
full_name =random.choice(first_name) +" "+ random.choice(last_name)
if full_name in full_name_dup_list:
generate_full_name()
else:
full_name_dup_list.append(full_name)
print(full_name)
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
result:
tony stark
tony wlliams
branden stark
branden smith
adam stark
agustin stark
agustin smith
stan smith
每个结果都是不重复的全名。
但是,我不想使用一种方法来检查已经创建的数组。 由于数组的大小增加并且返回值的数量增加,因此不幸的是,该函数可能会继续递归执行。
这是另一个计划: 像2深度陈述一样
import random
first_name = ['tony', 'adam', 'agustin', 'branden','stan']
last_name = ['smith', 'stark', 'wlliams']
class Index():
idx_first = 0
idx_last = 0
def generate_full_name():
full_name=first_name[Index.idx_first] + " " + last_name[Index.idx_last]
print(full_name)
Index.idx_last=Index.idx_last+1
if Index.idx_last== len(last_name)-1:
Index.idx_first=Index.idx_first+1
Index.idx_last=0
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
generate_full_name()
result:
tony smith
tony stark
adam smith
adam stark
agustin smith
agustin stark
branden smith
但这似乎是非随机的。
问题:我可以创建一个函数来输出全名列表(例如random),而不是检查现有的全名数组吗?
答案 0 :(得分:1)
一个选项是具有一组重复项,并使用生成器:
import random
first_name = ['tony', 'adam', 'agustin', 'branden','stan']
last_name = ['smith', 'stark', 'wlliams']
def generate_random_names(first, last):
duplicates = set()
while True:
f = random.choice(first)
l = random.choice(last)
if (f, l) in duplicates:
continue
duplicates.add((f, l))
yield f, l
for i, (f, l) in zip(range(1, 11), generate_random_names(first_name, last_name)):
print('{}. {} {}'.format(i, f, l))
打印:
1. stan wlliams
2. adam wlliams
3. tony wlliams
4. adam stark
5. tony stark
6. branden wlliams
7. stan stark
8. agustin smith
9. branden stark
10. agustin wlliams
另一个版本正在使用itertools.product
和random.sample
:
import random
from itertools import product
first_name = ['tony', 'adam', 'agustin', 'branden','stan']
last_name = ['smith', 'stark', 'wlliams']
print(random.sample([*product(first_name, last_name)], 10))
打印:
[('stan', 'wlliams'), ('tony', 'stark'), ('agustin', 'smith'), ('agustin', 'wlliams'), ('tony', 'smith'), ('tony', 'wlliams'), ('stan', 'stark'), ('branden', 'stark'), ('stan', 'smith'), ('branden', 'wlliams')]
答案 1 :(得分:1)
您知道可以使用多少个名称-仅len(first) * len(last)
。您可以生成此范围内的随机样本,然后进行一些数学运算以使组合与生成的数字匹配。对于范围内的给定整数,映射将为:
f = first_name[s // len(last_name)]
l = last_name[s % len(last_name)]
使用,您可以使用random.sample
然后建立名称:
import random
first_name = ['tony', 'adam', 'agustin', 'branden','stan']
last_name = ['smith', 'stark', 'wlliams']
total = len(first_name) * len(last_name)
sam = random.sample(range(total), 10)
[f'{first_name[s // len(last_name)]} {last_name[s % len(last_name)]}' for s in sam]
结果:
['adam stark',
'branden smith',
'agustin smith',
'stan wlliams',
'tony smith',
'stan stark',
'branden wlliams',
'agustin stark',
'stan smith',
'tony wlliams']
random.sample()
将引发错误,如果您尝试获取的总数超过了您想要的总数,那么您将需要欺骗。
答案 2 :(得分:0)
执行此操作的直接方法是使用哈希表:每个字符串都使用易于恢复的哈希码进行索引。 Python将为您轻松地做到这一点:将名称放入set
中,然后只需检查所生成的新名称是否已在集合中。做出新的选择,直到得到尚未使用的选择。
full_name_dup_set = set()
def generate_full_name():
full_name = random.choice(first_name) + " " + \
random.choice(last_name)
while full_name in full_name_dup_set:
full_name = random.choice(first_name) + " " + \
random.choice(last_name)
full_name_dup_set.add(full_name)
print(full_name)
答案 3 :(得分:0)
如果您想要姓和名的全部组合,可以在下面使用。产品是sql中的笛卡尔乘积。
['tony smith',
'tony stark',
'tony wlliams',
'adam smith',
'adam stark',
'adam wlliams',
'agustin smith',
'agustin stark',
'agustin wlliams',
'branden smith',
'branden stark',
'branden wlliams',
'stan smith',
'stan stark',
'stan wlliams']
结果:
#include<concurrent_vector.h>
答案 4 :(得分:0)
这是一种可以产生随机组合而无需预先生成所有名字对且没有迭代试验和错误循环的方法:
def generateNames():
names = dict()
allLast = set(range(len(last_name)))
while True:
if not names: names = { iFirst:[] for iFirst in range(len(first_name)) }
iFirst,usedLast = random.choice(list(names.items()))
remainingLast = list(allLast.difference(usedLast))
iLast = random.choice(remainingLast)
usedLast.append(iLast)
if not allLast.difference(usedLast): del names[iFirst]
yield first_name[iFirst]+" "+last_name[iLast]
randomName = generateNames()
for _ in range(10):
print(next(randomName))
tony wlliams
agustin smith
stan stark
stan wlliams
tony smith
branden wlliams
tony stark
branden stark
agustin stark
stan smith
这个想法是要跟踪用于每个名字的姓氏。它随机选择一个名字,然后从其余的那个名字中随机选择一个名字。这样,您总是在首次尝试时获得独特的组合(与尝试/错误方法相对,随着获得更多名称,统计学上将花费越来越多的时间)。
使用所有姓氏的姓氏时,该名字将被消除,并且不符合随后的随机选择的条件。
该解决方案实现为无限迭代器,如果您到达组合的末尾,它将循环回到开始。这样一来,您就可以在逻辑中的任意位置调用next(randomName),并根据需要调用多次。
使用更多内存但仍避免生成大量字符串的另一种方法是生成复合索引的随机列表,并在需要时根据索引建立全名。与预组装所有全名(但每个组合仍为一个整数)相比,这将占用更少的空间:
from collections import deque
firstCount = len(first_name)
lastCount = len(last_name)
fullCount = firstCount*lastCount
names = deque(random.sample(range(fullCount),fullCount))
def randomFullName():
names.rotate(1)
i = names[0]
iFirst = i // lastCount
iLast = i % lastCount
return first_name[iFirst] + " " + last_name[iLast]
for _ in range(10):
print(randomFullName())
在双端队列旋转时,即使调用次数超过组合次数,该函数也可以继续生成名称。这种方法不需要您事先知道将需要生成多少个名称。
答案 5 :(得分:0)
def main():
from random import sample
first_names = ["Bob", "Tom", "Jay"]
last_names = ["Jones", "Watson", "Smith"]
all_possible_names = [f"{first} {last}" for first in first_names for last in last_names]
print(sample(all_possible_names, k=4))
return 0
if __name__ == "__main__":
import sys
sys.exit(main())