我碰到了这个函数,它从数组中返回N个值的每个组合:
def combs(a, n):
if n == 0:
return [[]]
else:
return [(x + [y]) for x in combs(a,n-1) for y in a]
出于我自己的理解,我尝试使用嵌套的for循环将其转换为函数:
def combinations(array,n):
if n == 0:
return [[]]
else:
for i in array:
for j in combinations(array, n-1):
return [j + [i]]
但是我得到的结果与预期不同。
>>> threes = ['aA','bB','cC']
>>>
>>> combs(threes,2)
[['aA', 'aA'], ['aA', 'bB'], ['aA', 'cC'], ['bB', 'aA'], ['bB', 'bB'], ['bB', 'cC'], ['cC', 'aA'], ['cC', 'bB'], ['cC', 'cC']]
>>>
>>> combinations(threes,2)
[['aA', 'aA']]
>>>
我尝试了return [j+[i]]
行的各种版本,但都没有成功。以下是一些示例:
return (j + [i])
Traceback (most recent call last):
File "...", line 24, in <module>
print(combinations(threes,2))
File "...", line 16, in combinations
return (j + [i])
TypeError: can only concatenate str (not "list") to str
。
return j + [i]
Traceback (most recent call last):
File "...", line 24, in <module>
print(combinations(threes,2))
File "...", line 16, in combinations
return j + [i]
TypeError: can only concatenate str (not "list") to str
为什么第一个函数的列表理解返回的内容与我的扩展嵌套for循环版本不同?
将第一个函数的列表理解和返回值转换为嵌套的for循环策略的正确(起作用)的方法是什么?
答案 0 :(得分:4)
如果您真的想使它等效,那么您需要做一个return
。当您执行理解时,您将以某种原子方式创建列表,即,只有在完全构建列表之后才能访问列表///在列表理解(构建)完成之前,无法访问列表。要在没有列表理解的情况下执行此操作,您需要填充一个可变容器,然后在末尾执行一次返回:
def combinations(array,n):
if n == 0:
return [[]]
else:
result = []
for i in array:
for j in combinations(array, n-1):
result.append(j + [i])
return result
这是解决问题的有效方法,但我还将探索创建一个生成器函数。与通常只能从一个功能return
一次的普通情况不同,生成器允许您从该功能多次yield
一次。
在您不想在创建过程中阻塞,不想强制使用特定容器的情况下,或者通常在简化逻辑的情况下,此策略很有用。此外,如果您只需要遍历结果而实际上并不需要一次整个列表,那么它的另一个优点是不会将整个序列加载到内存中。
通常,我发现这些优势是创建像这样的大多数函数的充分理由。对于短列表,理解或标准列表创建(如上例所示)足以解决问题。
一个警告是,您可能必须根据应用程序的需要将结果打包到一个容器中。这是因为生成器会按需创建每个新条目,然后简单地流式传输结果:
def combinations(array,n):
if n == 0:
yield []
else:
for i in array:
for j in combinations(array, n-1):
yield j + [i]
>>> print(list(combinations(['aA','bB','cC'], 2)))
[['aA', 'aA'], ['bB', 'aA'], ['cC', 'aA'], ['aA', 'bB'], ['bB', 'bB'], ['cC', 'bB'], ['aA', 'cC'], ['bB', 'cC'], ['cC', 'cC']]
如果您想利用生成器的优点来理解,那么可以使用生成器理解(用( )
代替[ ]
)和yield from
语句:>
def combs(a, n):
if n == 0:
yield []
else:
yield from (x + [y] for x in combs(a, n - 1) for y in a)
答案 1 :(得分:1)
Name