Applying a method with no return value for each list item

Is there a way to use methods with no return value, such as random.shuffle in list comprehension?

>>> import pprint >>> import random >>> >>> L = [ random.shuffle(range(5)) for x in range(5)] >>> >>> print L [None, None, None, None, None] 

This is a for loop that applies the random.shuffle method to each element of my list:

 >>> L = [ range(5) for x in range(5) ] >>> pprint.pprint(L) [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]] >>> for element in L: ... random.shuffle(element) ... >>> pprint.pprint(L) [[2, 0, 3, 1, 4], [2, 0, 1, 4, 3], [4, 1, 3, 0, 2], [1, 2, 4, 3, 0], [1, 3, 0, 2, 4]] 

I can use a card that shuffles the original list as a side effect, but returns a None list

 >>> L = [ range(5) for x in range(5) ] >>> pprint.pprint(L) [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]] >>> map(random.shuffle, L) [None, None, None, None, None] >>> pprint.pprint(L) [[3, 0, 4, 1, 2], [2, 3, 0, 1, 4], [2, 3, 1, 4, 0], [4, 2, 0, 3, 1], [1, 3, 0, 2, 4]] 

how shuffling a list does this:

 >>> L = [ range(5) for x in range(5) ] >>> pprint.pprint(L) [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]] >>> L1 = [ random.shuffle(x) for x in L ] >>> pprint.pprint(L1) [None, None, None, None, None] >>> pprint.pprint(L) [[1, 4, 0, 2, 3], [0, 4, 1, 3, 2], [2, 3, 4, 0, 1], [4, 1, 0, 2, 3], [2, 0, 4, 3, 1]] 

Many questions and answers about stack overflows already indicate that using a card or lc for a side effect is bad practice. I was wondering if there is any correct way to use the method without return value in list comprehension.

Writes a method to nullify the non-return method in one way:

 >>> def shuffled(L): ... ret_val = L[:] ... random.shuffle(ret_val) ... return ret_val ... >>> L = [ shuffled(range(5)) for x in range(5)] >>> pprint.pprint(L) [[2, 1, 0, 4, 3], [4, 0, 3, 1, 2], [4, 2, 3, 0, 1], [1, 0, 4, 2, 3], [2, 4, 3, 0, 1]] >>> 
+6
source share
2 answers

No lists are intended for use with functions that have return values. This is the definition of their semantics :

Matching lists provides a quick way to create lists without resorting to using maps (), filter (), and / or lambda. The resulting list definition is often clearer than lists constructed using these constructs. each list consists of an expression followed by a for clause, then zero or more for or if a clause. The result will be a list as a result of evaluating the expression in the context of the for and if statements that follow it.

After reading this, it should be clear that "understanding the list from a function that does not have a return value" is an oxymoron.

Just use the for loop for something "one off":

 import random L = [] for x in range(5): l = range(5) random.shuffle(l) L.append(l) 

Clean and simple. Your shuffled function is also great and can be used in list comprehension.

+8
source

Eli is absolutely right. But I would go for something more concise:

 import random L = [range(5) for each in xrange(5)] for each in L: random.shuffle(each) 

[edit]

OTOH you can use random.sample() :

 from random import sample xr = xrange(5) L = [sample(xr, 5) for each in xr] 
+4
source

All Articles