简体   繁体   中英

Python itertools function: inconsistent output

I have been pondering on why the output of these scripts is inconsisten. Could anyone help me on this?

import itertools
from itertools import tee
from itertools import islice

words = ['Salad','with','Chocolate','and','potatoes']
nwise = lambda xs,n=2: zip(*(islice(xs,idx,None) for idx,xs in enumerate(tee(xs,n))))
doubles = list(map(lambda x: " ".join(x), nwise(words,2)))
triples = list(map(lambda x: " ".join(x), nwise(words,3)))
quadrouples = list(map(lambda x: " ".join(x), nwise(words,4)))
words.extend(doubles)
words.extend(triples)
words.extend(quadrouples)
print(words)

The result of this is ['Salad', 'with', 'Chocolate', 'and', 'potatoes', 'Salad with', 'with Chocolate', 'Chocolate and', 'and potatoes', 'Salad with Chocolate', 'with Chocolate and', 'Chocolate and potatoes', 'Salad with Chocolate and', 'with Chocolate and potatoes']

import itertools
from itertools import tee
from itertools import islice

words = ['Salad','with','Chocolate','and','potatoes']
nwise = lambda xs,n=2: zip(*(islice(xs,idx,None) for idx,xs in enumerate(tee(xs,n))))
for i in range(2,5):
    new = list(map(lambda x: " ".join(x), nwise(words,i)))
    words.extend(new)
print(words)

The result of this is ['Salad', 'with', 'Chocolate', 'and', 'potatoes', 'Salad with', 'with Chocolate', 'Chocolate and', 'and potatoes', 'Salad with Chocolate', 'with Chocolate and', 'Chocolate and potatoes', 'and potatoes Salad with', 'potatoes Salad with with Chocolate', 'Salad with with Chocolate Chocolate and', 'with Chocolate Chocolate and and potatoes', 'Salad with Chocolate and', 'with Chocolate and potatoes', 'Chocolate and potatoes Salad with', 'and potatoes Salad with with Chocolate', 'potatoes Salad with with Chocolate Chocolate and', 'Salad with with Chocolate Chocolate and and potatoes', 'with Chocolate Chocolate and and potatoes Salad with Chocolate', 'Chocolate and and potatoes Salad with Chocolate with Chocolate and', 'and potatoes Salad with Chocolate with Chocolate and Chocolate and potatoes', 'Salad with Chocolate with Chocolate and Chocolate and potatoes and potatoes Salad with', 'with Chocolate and Chocolate and potatoes and potatoes Salad with potatoes Salad with with Chocolate', 'Chocolate and potatoes and potatoes Salad with potatoes Salad with with Chocolate Salad with with Chocolate Chocolate and', 'and potatoes Salad with potatoes Salad with with Chocolate Salad with with Chocolate Chocolate and with Chocolate Chocolate and and potatoes'] ['Salad', 'with', 'Chocolate', 'and', 'potatoes', 'Salad with', 'with Chocolate', 'Chocolate and', 'and potatoes', 'Salad with Chocolate', 'with Chocolate and', 'Chocolate and potatoes', 'and potatoes Salad with', 'potatoes Salad with with Chocolate', 'Salad with with Chocolate Chocolate and', 'with Chocolate Chocolate and and potatoes', 'Salad with Chocolate and', 'with Chocolate and potatoes', 'Chocolate and potatoes Salad with', 'and potatoes Salad with with Chocolate', 'potatoes Salad with with Chocolate Chocolate and', 'Salad with with Chocolate Chocolate and and potatoes', 'with Chocolate Chocolate and and potatoes Salad with Chocolate', 'Chocolate and and potatoes Salad with Chocolate with Chocolate and', 'and potatoes Salad with Chocolate with Chocolate and Chocolate and potatoes', 'Salad with Chocolate with Chocolate and Chocolate and potatoes and potatoes Salad with', 'with Chocolate and Chocolate and potatoes and potatoes Salad with potatoes Salad with with Chocolate', 'Chocolate and potatoes and potatoes Salad with potatoes Salad with with Chocolate Salad with with Chocolate Chocolate and', 'and potatoes Salad with potatoes Salad with with Chocolate Salad with with Chocolate Chocolate and with Chocolate Chocolate and and potatoes']

Why does the for loop with the range() function produce inconsistent results to the line-by-line approach?

It is generally safer to create a new collection when looping to modify it.

Extend to a new list, eg words_ :

...
words_ = []
for i in range(2, 5):
    new = list(map(lambda x: " ".join(x), nwise(words,i)))
    words_.extend(new)
print(words_)

Alternatively, extend the existing words list with a new list of desired results.

Replace:

...
for i in range(2,5):
    new = list(map(lambda x: " ".join(x), nwise(words,i)))
    words.extend(new)
...

with

... 
new = [" ".join(x) for i in range(2, 5) for x in nwise(words,i)]
words.extend(new)
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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