简体   繁体   English

如何将两个列表的所有组合拆分N次?

[英]How to split all combinations of two lists N times cleaner?

Pardon if the question is titled confusingly. 如果问题的标题令人困惑,请原谅。 I couldn't think of a better way to word it. 我想不出更好的措辞了。 Anyway, I have a Python program that accepts a list of first names and a list of last names. 无论如何,我有一个Python程序,该程序接受名字列表和姓氏列表。 It then "splits" the two into all of their combinations, with a maximum of 5 results. 然后,将两者“拆分”为所有组合,最多可获得5个结果。 The code explains it better: 该代码对其进行了更好的解释:

def getLists(firstNames, lastNames, resultCount):
    firstNameCount = len(firstNames)
    lastNameCount = len(lastNames)

    if firstNameCount >= resultCount:
        # Return the last name list as is.
        return [firstNames[i * firstNameCount / resultCount:(i + 1) * firstNameCount / resultCount] for i in xrange(resultCount)], [lastNames for _ in xrange(resultCount)]

    else:
        lastNameLists = []
        firstNameLists = [[firstNames[i % firstNameCount]] for i in xrange(resultCount)]

        for i in xrange(resultCount):
            firstName = firstNameLists[i]
            total = firstNameLists.count(firstName)
            already = total - firstNameLists[i:].count(firstName)
            lastNameLists.append(lastNames[already * lastNameCount / total:(already + 1) * lastNameCount / total])

        # Return the last names, split depending on how many results and first names.
        return firstNameLists, lastNameLists

If there are less first names than the maximum (5), the first names are repeated until the maximum and the last names are distributed among the first names: 如果名字少于最大值(5),则重复名字,直到最大值和姓氏分配在名字之间:

firstNames = ['firstName{}'.format(i) for i in xrange(1, 3)]
lastNames = ['lastName{}'.format(i) for i in xrange(1, 8)]
comboCount = len(firstNames) * len(lastNames)
resultCount = min(comboCount, 5)
firstNameLists, lastNameLists = getLists(firstNames, lastNames, resultCount)

for i in xrange(resultCount):
    print 'Result #{}:\nFirst Names: {}\nLast Names: {}'.format(i + 1, firstNameLists[i], lastNameLists[i])
    print

Output: 输出:

Result #1:
First Names: ['firstName1']
Last Names: ['lastName1', 'lastName2']

Result #2:
First Names: ['firstName2']
Last Names: ['lastName1', 'lastName2', 'lastName3']

Result #3:
First Names: ['firstName1']
Last Names: ['lastName3', 'lastName4']

Result #4:
First Names: ['firstName2']
Last Names: ['lastName4', 'lastName5', 'lastName6', 'lastName7']

Result #5:
First Names: ['firstName1']
Last Names: ['lastName5', 'lastName6', 'lastName7']

If there are more first names than the maximum (5), the first names are distributed as evenly as possible and the last names are copied for each: 如果名字多于最大值(5),则名字将尽可能均匀地分布,并为每个名字复制姓氏:

firstNames = ['firstName{}'.format(i) for i in xrange(1, 8)]
lastNames = ['lastName{}'.format(i) for i in xrange(1, 8)]
comboCount = len(firstNames) * len(lastNames)
resultCount = min(comboCount, 5)
firstNameLists, lastNameLists = getLists(firstNames, lastNames, resultCount)

for i in xrange(resultCount):
    print 'Result #{}:\nFirst Names: {}\nLast Names: {}'.format(i + 1, firstNameLists[i], lastNameLists[i])
    print

Output: 输出:

Result #1:
First Names: ['firstName1']
Last Names: ['lastName1', 'lastName2', 'lastName3', 'lastName4', 'lastName5', 'lastName6', 'lastName7']

Result #2:
First Names: ['firstName2']
Last Names: ['lastName1', 'lastName2', 'lastName3', 'lastName4', 'lastName5', 'lastName6', 'lastName7']

Result #3:
First Names: ['firstName3', 'firstName4']
Last Names: ['lastName1', 'lastName2', 'lastName3', 'lastName4', 'lastName5', 'lastName6', 'lastName7']

Result #4:
First Names: ['firstName5']
Last Names: ['lastName1', 'lastName2', 'lastName3', 'lastName4', 'lastName5', 'lastName6', 'lastName7']

Result #5:
First Names: ['firstName6', 'firstName7']
Last Names: ['lastName1', 'lastName2', 'lastName3', 'lastName4', 'lastName5', 'lastName6', 'lastName7']

How could I make getLists more efficient, readable, and/or cleaner? 如何使getLists更高效,可读性和/或更清洁?

The demo is Python3, if you use Python2, try to make a little code change if possible: 该演示是Python3,如果您使用Python2,请尝试进行一些可能的代码更改:

firstNames = ['firstName{}'.format(i) for i in range(1, 3)]
lastNames = ['lastName{}'.format(i) for i in range(1, 2)]

from itertools import product, islice

print(list(islice(product(firstNames, lastNames), 5)))

the islice ensure it returns the first 5 result, if the results is less than 5, it's still OK. islice确保返回前5个结果,如果结果小于5,则仍然可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM