[英]Expanding python's list comprehension into nested for loops — strange results
我遇到這個函數來返回數組中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循環版本不同?
將第一個函數的list-comprehension和return值轉換為嵌套for循環策略的正確(運行)方法是什么?
如果你真的想要使它等效,那么你需要做一次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)
> The list comprehension always returns a result list.
>
> But in your nested loop case you are not returning list so little
> modify in your case
>
>
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
In this you are returning the list of all iterations ..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.