通过组合名字和姓氏数组中的值来创建唯一的名称

时间:2019-06-21 17:11:44

标签: python python-3.x

我有两个数组,我想通过组合这两个数组来创建一个名称。 但是,不应重复。

除了查找名称结果值数组的递归方法之外,我还可以像返回随机名称一样返回随机名称吗?

最简单的方法是将随机生成的名称存储在列表中,并在每次创建新名称(如下所示)时查找列表。

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),而不是检查现有的全名数组吗?

6 个答案:

答案 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.productrandom.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())
  1. 生成所有可能名称的列表。
  2. 随机抽取一个样本(对于我来说,不能超过9个样本)