我正在寻找在Python中创建一个项目和一个列表之间的排列的列表。例如:
[nyc]
[strawberry, apple, banana, orange, pineapple, ..]
我正在尝试最多包含四个单词,并且始终包含“ nyc”。该顺序很重要,并且必须始终包含“ nyc”。例如:
nyc
strawberry-nyc
nyc-strawberry
strawberry-apple-nyc
strawberry-apple-banana-nyc
到目前为止,我所做的就是将所有单词放入一个列表,包括一些空白,然后使用itertools创建所有排列,然后删除所有不包含“ nyc”的行:
import itertools
import re
# include blanks to allow for four-word permutations to have just one, two, or three words
adjectives = ['', '', '', 'nyc', 'strawberry', 'apple', 'banana', 'orange', 'pineapple']
names = ['-'.join(x) for x in itertools.permutations(adjectives, 4)]
# limit to permutations that contain 'nyc'
names = [x for x in names if 'nyc' in x]
# since joining blanks using "-", remove the multiple dashes when this happens
# and also remove leading or trailing dashes
names = [re.sub(r"-+", "-", x) for x in names]
names = [re.sub(r"-+$", "", x) for x in names]
names = [re.sub(r"^-+", "", x) for x in names]
# remove duplicates, since blank can be added multiple times, sort for visual clarity
names = sorted(list(set(names)))
print(names)
我一直在浏览itertools和这里的一些问题,以为我必须忽略一个简单的解决方案。哪种方法更有效?
答案 0 :(得分:2)
这对我来说就像一个简单的解决方案。进行排列,然后将“ nyc”添加到每个位置。我避免将太多的中间结果构建为完整列表,因此,与涉及构建列表并修剪它们的解决方案相比,这应该使用更少的内存。我不确定性能。
import itertools
adjectives = ['strawberry', 'apple', 'banana', 'orange', 'pineapple']
root = 'nyc'
targetlength = 4
def rootpermute(root, adjectives, N):
for group in itertools.permutations(adjectives, N-1):
for position in range(len(group) + 1):
newgroup = list(group)
newgroup.insert(position, root)
yield newgroup
perms = itertools.chain.from_iterable(rootpermute(root, adjectives, N)
for N in range(1, targetlength+1))
names = ['-'.join(group) for group in perms]
答案 1 :(得分:1)
您可以在主列表中找到所有项的组合,然后应用笛卡尔积:
def cart_p(d, c =[]):
if not d:
yield c
else:
for i in d[0]:
yield from cart_p(d[1:], c+[i])
def combo(d, c = []):
if len(c) == 3:
yield c
else:
yield c
for i in d:
if i not in c:
yield from combo(d, c+[i])
def group_result(r):
for a, b in r:
for i in range(1, len(a)):
yield '-'.join(a[:i]+[b]+a[i:])
yield from {'-'.join(a+[b]), '-'.join([b]+a)}
data = ['strawberry', 'apple', 'banana', 'orange', 'pineapple']
print(list(group_result(list(cart_p([list(combo(data)), ['nyc']])))))
输出:
['nyc', 'nyc-strawberry', 'strawberry-nyc', 'strawberry-nyc-apple', 'nyc-strawberry-apple', 'strawberry-apple-nyc', 'strawberry-nyc-apple-banana', 'strawberry-apple-nyc-banana', 'strawberry-apple-banana-nyc', 'nyc-strawberry-apple-banana', 'strawberry-nyc-apple-orange', 'strawberry-apple-nyc-orange', 'strawberry-apple-orange-nyc', 'nyc-strawberry-apple-orange', 'strawberry-nyc-apple-pineapple', 'strawberry-apple-nyc-pineapple', 'strawberry-apple-pineapple-nyc', 'nyc-strawberry-apple-pineapple', 'strawberry-nyc-banana', 'nyc-strawberry-banana', 'strawberry-banana-nyc', 'strawberry-nyc-banana-apple', 'strawberry-banana-nyc-apple', 'strawberry-banana-apple-nyc', 'nyc-strawberry-banana-apple', 'strawberry-nyc-banana-orange', 'strawberry-banana-nyc-orange', 'nyc-strawberry-banana-orange', 'strawberry-banana-orange-nyc', 'strawberry-nyc-banana-pineapple', 'strawberry-banana-nyc-pineapple', 'nyc-strawberry-banana-pineapple', 'strawberry-banana-pineapple-nyc', 'strawberry-nyc-orange', 'strawberry-orange-nyc', 'nyc-strawberry-orange', 'strawberry-nyc-orange-apple', 'strawberry-orange-nyc-apple', 'nyc-strawberry-orange-apple', 'strawberry-orange-apple-nyc', 'strawberry-nyc-orange-banana', 'strawberry-orange-nyc-banana', 'nyc-strawberry-orange-banana', 'strawberry-orange-banana-nyc', 'strawberry-nyc-orange-pineapple', 'strawberry-orange-nyc-pineapple', 'nyc-strawberry-orange-pineapple', 'strawberry-orange-pineapple-nyc', 'strawberry-nyc-pineapple', 'strawberry-pineapple-nyc', 'nyc-strawberry-pineapple', 'strawberry-nyc-pineapple-apple', 'strawberry-pineapple-nyc-apple', 'nyc-strawberry-pineapple-apple', 'strawberry-pineapple-apple-nyc', 'strawberry-nyc-pineapple-banana', 'strawberry-pineapple-nyc-banana', 'nyc-strawberry-pineapple-banana', 'strawberry-pineapple-banana-nyc', 'strawberry-nyc-pineapple-orange', 'strawberry-pineapple-nyc-orange', 'strawberry-pineapple-orange-nyc', 'nyc-strawberry-pineapple-orange', 'apple-nyc', 'nyc-apple', 'apple-nyc-strawberry', 'apple-strawberry-nyc', 'nyc-apple-strawberry', 'apple-nyc-strawberry-banana', 'apple-strawberry-nyc-banana', 'apple-strawberry-banana-nyc', 'nyc-apple-strawberry-banana', 'apple-nyc-strawberry-orange', 'apple-strawberry-nyc-orange', 'nyc-apple-strawberry-orange', 'apple-strawberry-orange-nyc', 'apple-nyc-strawberry-pineapple', 'apple-strawberry-nyc-pineapple', 'apple-strawberry-pineapple-nyc', 'nyc-apple-strawberry-pineapple', 'apple-nyc-banana', 'apple-banana-nyc', 'nyc-apple-banana', 'apple-nyc-banana-strawberry', 'apple-banana-nyc-strawberry', 'nyc-apple-banana-strawberry', 'apple-banana-strawberry-nyc', 'apple-nyc-banana-orange', 'apple-banana-nyc-orange', 'apple-banana-orange-nyc', 'nyc-apple-banana-orange', 'apple-nyc-banana-pineapple', 'apple-banana-nyc-pineapple', 'nyc-apple-banana-pineapple', 'apple-banana-pineapple-nyc', 'apple-nyc-orange', 'nyc-apple-orange', 'apple-orange-nyc', 'apple-nyc-orange-strawberry', 'apple-orange-nyc-strawberry', 'nyc-apple-orange-strawberry', 'apple-orange-strawberry-nyc', 'apple-nyc-orange-banana', 'apple-orange-nyc-banana', 'apple-orange-banana-nyc', 'nyc-apple-orange-banana', 'apple-nyc-orange-pineapple', 'apple-orange-nyc-pineapple', 'apple-orange-pineapple-nyc', 'nyc-apple-orange-pineapple', 'apple-nyc-pineapple', 'nyc-apple-pineapple', 'apple-pineapple-nyc', 'apple-nyc-pineapple-strawberry', 'apple-pineapple-nyc-strawberry', 'apple-pineapple-strawberry-nyc', 'nyc-apple-pineapple-strawberry', 'apple-nyc-pineapple-banana', 'apple-pineapple-nyc-banana', 'apple-pineapple-banana-nyc', 'nyc-apple-pineapple-banana', 'apple-nyc-pineapple-orange', 'apple-pineapple-nyc-orange', 'apple-pineapple-orange-nyc', 'nyc-apple-pineapple-orange', 'nyc-banana', 'banana-nyc', 'banana-nyc-strawberry', 'nyc-banana-strawberry', 'banana-strawberry-nyc', 'banana-nyc-strawberry-apple', 'banana-strawberry-nyc-apple', 'banana-strawberry-apple-nyc', 'nyc-banana-strawberry-apple', 'banana-nyc-strawberry-orange', 'banana-strawberry-nyc-orange', 'banana-strawberry-orange-nyc', 'nyc-banana-strawberry-orange', 'banana-nyc-strawberry-pineapple', 'banana-strawberry-nyc-pineapple', 'nyc-banana-strawberry-pineapple', 'banana-strawberry-pineapple-nyc', 'banana-nyc-apple', 'banana-apple-nyc', 'nyc-banana-apple', 'banana-nyc-apple-strawberry', 'banana-apple-nyc-strawberry', 'banana-apple-strawberry-nyc', 'nyc-banana-apple-strawberry', 'banana-nyc-apple-orange', 'banana-apple-nyc-orange', 'nyc-banana-apple-orange', 'banana-apple-orange-nyc', 'banana-nyc-apple-pineapple', 'banana-apple-nyc-pineapple', 'nyc-banana-apple-pineapple', 'banana-apple-pineapple-nyc', 'banana-nyc-orange', 'banana-orange-nyc', 'nyc-banana-orange', 'banana-nyc-orange-strawberry', 'banana-orange-nyc-strawberry', 'banana-orange-strawberry-nyc', 'nyc-banana-orange-strawberry', 'banana-nyc-orange-apple', 'banana-orange-nyc-apple', 'nyc-banana-orange-apple', 'banana-orange-apple-nyc', 'banana-nyc-orange-pineapple', 'banana-orange-nyc-pineapple', 'banana-orange-pineapple-nyc', 'nyc-banana-orange-pineapple', 'banana-nyc-pineapple', 'nyc-banana-pineapple', 'banana-pineapple-nyc', 'banana-nyc-pineapple-strawberry', 'banana-pineapple-nyc-strawberry', 'banana-pineapple-strawberry-nyc', 'nyc-banana-pineapple-strawberry', 'banana-nyc-pineapple-apple', 'banana-pineapple-nyc-apple', 'banana-pineapple-apple-nyc', 'nyc-banana-pineapple-apple', 'banana-nyc-pineapple-orange', 'banana-pineapple-nyc-orange', 'nyc-banana-pineapple-orange', 'banana-pineapple-orange-nyc', 'orange-nyc', 'nyc-orange', 'orange-nyc-strawberry', 'nyc-orange-strawberry', 'orange-strawberry-nyc', 'orange-nyc-strawberry-apple', 'orange-strawberry-nyc-apple', 'nyc-orange-strawberry-apple', 'orange-strawberry-apple-nyc', 'orange-nyc-strawberry-banana', 'orange-strawberry-nyc-banana', 'nyc-orange-strawberry-banana', 'orange-strawberry-banana-nyc', 'orange-nyc-strawberry-pineapple', 'orange-strawberry-nyc-pineapple', 'nyc-orange-strawberry-pineapple', 'orange-strawberry-pineapple-nyc', 'orange-nyc-apple', 'nyc-orange-apple', 'orange-apple-nyc', 'orange-nyc-apple-strawberry', 'orange-apple-nyc-strawberry', 'orange-apple-strawberry-nyc', 'nyc-orange-apple-strawberry', 'orange-nyc-apple-banana', 'orange-apple-nyc-banana', 'nyc-orange-apple-banana', 'orange-apple-banana-nyc', 'orange-nyc-apple-pineapple', 'orange-apple-nyc-pineapple', 'nyc-orange-apple-pineapple', 'orange-apple-pineapple-nyc', 'orange-nyc-banana', 'nyc-orange-banana', 'orange-banana-nyc', 'orange-nyc-banana-strawberry', 'orange-banana-nyc-strawberry', 'orange-banana-strawberry-nyc', 'nyc-orange-banana-strawberry', 'orange-nyc-banana-apple', 'orange-banana-nyc-apple', 'nyc-orange-banana-apple', 'orange-banana-apple-nyc', 'orange-nyc-banana-pineapple', 'orange-banana-nyc-pineapple', 'orange-banana-pineapple-nyc', 'nyc-orange-banana-pineapple', 'orange-nyc-pineapple', 'nyc-orange-pineapple', 'orange-pineapple-nyc', 'orange-nyc-pineapple-strawberry', 'orange-pineapple-nyc-strawberry', 'nyc-orange-pineapple-strawberry', 'orange-pineapple-strawberry-nyc', 'orange-nyc-pineapple-apple', 'orange-pineapple-nyc-apple', 'nyc-orange-pineapple-apple', 'orange-pineapple-apple-nyc', 'orange-nyc-pineapple-banana', 'orange-pineapple-nyc-banana', 'orange-pineapple-banana-nyc', 'nyc-orange-pineapple-banana', 'nyc-pineapple', 'pineapple-nyc', 'pineapple-nyc-strawberry', 'nyc-pineapple-strawberry', 'pineapple-strawberry-nyc', 'pineapple-nyc-strawberry-apple', 'pineapple-strawberry-nyc-apple', 'nyc-pineapple-strawberry-apple', 'pineapple-strawberry-apple-nyc', 'pineapple-nyc-strawberry-banana', 'pineapple-strawberry-nyc-banana', 'nyc-pineapple-strawberry-banana', 'pineapple-strawberry-banana-nyc', 'pineapple-nyc-strawberry-orange', 'pineapple-strawberry-nyc-orange', 'nyc-pineapple-strawberry-orange', 'pineapple-strawberry-orange-nyc', 'pineapple-nyc-apple', 'pineapple-apple-nyc', 'nyc-pineapple-apple', 'pineapple-nyc-apple-strawberry', 'pineapple-apple-nyc-strawberry', 'pineapple-apple-strawberry-nyc', 'nyc-pineapple-apple-strawberry', 'pineapple-nyc-apple-banana', 'pineapple-apple-nyc-banana', 'nyc-pineapple-apple-banana', 'pineapple-apple-banana-nyc', 'pineapple-nyc-apple-orange', 'pineapple-apple-nyc-orange', 'pineapple-apple-orange-nyc', 'nyc-pineapple-apple-orange', 'pineapple-nyc-banana', 'nyc-pineapple-banana', 'pineapple-banana-nyc', 'pineapple-nyc-banana-strawberry', 'pineapple-banana-nyc-strawberry', 'nyc-pineapple-banana-strawberry', 'pineapple-banana-strawberry-nyc', 'pineapple-nyc-banana-apple', 'pineapple-banana-nyc-apple', 'pineapple-banana-apple-nyc', 'nyc-pineapple-banana-apple', 'pineapple-nyc-banana-orange', 'pineapple-banana-nyc-orange', 'nyc-pineapple-banana-orange', 'pineapple-banana-orange-nyc', 'pineapple-nyc-orange', 'pineapple-orange-nyc', 'nyc-pineapple-orange', 'pineapple-nyc-orange-strawberry', 'pineapple-orange-nyc-strawberry', 'nyc-pineapple-orange-strawberry', 'pineapple-orange-strawberry-nyc', 'pineapple-nyc-orange-apple', 'pineapple-orange-nyc-apple', 'nyc-pineapple-orange-apple', 'pineapple-orange-apple-nyc', 'pineapple-nyc-orange-banana', 'pineapple-orange-nyc-banana', 'nyc-pineapple-orange-banana', 'pineapple-orange-banana-nyc']
>>>len(output)
311
答案 2 :(得分:1)
如何排列两次?对于较长的列表,效率不是很高。对于更长的列表,您可以仅在所有位置插入nyc而不是置换。我将为您保留内循环优化。
import itertools
import re
adjectives = ['strawberry', 'apple', 'banana', 'orange', 'pineapple']
root = 'nyc'
for i in range(len(adjectives)):
adj_perm = itertools.permutations(adjectives, i+1)
for perm in adj_perm:
perm = list(perm)
perm.append(root)
print(len(perm))
combined_perm = itertools.permutations(perm, len(perm))
for final_perm in combined_perm:
print("-".join(final_perm))
答案 3 :(得分:0)
IIUC,您可以将以下功能与permuations
和列表理解结合使用,方法是在每个索引处插入N
,以获得所有长度的root
组合。
from itertools import permutations, chain
def getPerms(N, root, adjectives):
"""N is the number of elements from adjectives to include in the output"""
if N == 0:
return [root]
return [
"-".join(p[:i] + (root, ) + p[i:])
for p in permutations(adjectives, N)
for i in range(N)
]
现在您可以调用此函数以获取所需的长度组合:
print(getPerms(0, root, adjectives))
#['nyc']
print(getPerms(1, root, adjectives))
#['nyc-strawberry', 'nyc-apple', 'nyc-banana', 'nyc-orange', 'nyc-pineapple']
因此,要获得最终所需的输出,可以将对getPerms
的调用链接在一起,最长为4
:
res = list(chain.from_iterable(getPerms(i, root, adjectives) for i in range(4)))
print(res)
#['nyc',
# 'nyc-strawberry',
# 'nyc-apple',
# 'nyc-banana',
# 'nyc-orange',
# 'nyc-pineapple',
# 'nyc-strawberry-apple',
# 'strawberry-nyc-apple',
# 'nyc-strawberry-banana',
# 'strawberry-nyc-banana',
#... skipping ...
#'pineapple-nyc-orange-apple',
# 'pineapple-orange-nyc-apple',
# 'nyc-pineapple-orange-banana',
# 'pineapple-nyc-orange-banana',
# 'pineapple-orange-nyc-banana']
这将产生226个元素的输出列表:
print(len(res))
#226