What does this function do? (Python Iterators)

def partition(n, iterable): p = izip_longest(*([iter(iterable)] * n)) r = [] for x in p: print(x) #I added this s = set(x) s.discard(None) r.append(list(s)) return r 

This is actually in posting jobs on SO and being a newbie, I thought it was interesting. Thus, you get the result as follows:

 partition(5, L) (1, 2, 3, 4, None) Out[86]: [[1, 2, 3, 4]] 

This is already confusing for me, because I thought that izip_longest(*([iter(iterable)] * n)) would run the izip_longest function in a list of n identical iterators, so I would expect output first (1,1,1,1,1) , and then the conclusion (2,2,2,2,2) and so on.

So a short version of my question what happens to this line:

  p = izip_longest(*([iter(iterable)] * n)) 

Legible, I would think that [iter (iterable)] * n creates a list of length n identical iterations, all pointing to the same thing - what it does on the command line, but it doesn't look like what it does here, based on from the output indicated above.

I also thought that * at the beginning ...longest(*... was there, since the list has an unknown length, but I don’t think it makes sense. What is the first * character executed inside the function call? that this simply indicates a list of arguments of unknown length ...

So, at the end of the day, I was completely lost. Can anyone get through this syntax?

Thanks so much for any input!


Thanks for all the helpful answers, everyone. I'm not sure if I'm on the answer or on the question here, but it seems to me that this list comprehension will do the same for lists and tuples (I understand that iterators will also apply to dictionaries, user classes, etc. )

 [L[i*n:(i+1)*n] for i in range(int(ceil(len(L)/float(n)))) ] 
+5
source share
2 answers

Given:

 >>> li [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 

There is a common Python idiom that uses zip in combination with iter and * to split a list into a flat list into a list of lists of n lengths:

 >>> n=3 >>> zip(*([iter(li)] * n)) [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 14), (15, 16, 17), (18, 19, 20)] 

However, if n not an even multiple of the total length, the final list is truncated:

 >>> n=4 >>> zip(*([iter(li)] * n)) [(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15), (16, 17, 18, 19)] 

You can use izip_longest to use the full list populated with the selected value for incomplete subscriptions:

 >>> list(izip_longest(*([iter(li)] * n))) [(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15), (16, 17, 18, 19), (20, None, None, None)] 
+6
source

iter(my_list) converts the list to iterable (i.e. the one where the elements are consumed as they are viewed)

[my_iter]*5 creates a new list [my_iter,my_iter,my_iter,my_iter,my_iter] , in which all my_iter point to the same exact iterator

 zip(*[my_iter,my_iter,my_iter,my_iter,my_iter]) 

coincides with

 zip(my_iter,my_iter,my_iter,my_iter,my_iter) 

(splat just unpacks the list / tuple), which basically just returns the list 5xlen(my_list)//5 2d

you can simplify it with regular zip

 #this method will have no `None` entries new_list_partitioned = zip(*[iter(big_list)]*N) + [big_list[-(len(big_list)%N):],] 
+6
source

All Articles