有没有办法在列表推导中使用没有返回值的方法,例如random.shuffle?
>>> import pprint
>>> import random
>>>
>>> L = [ random.shuffle(range(5)) for x in range(5)]
>>>
>>> print L
[None, None, None, None, None]
这是将random.shuffle方法应用于列表中每个项目的for循环:
>>> 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]]
我可以使用map,这是一个副作用混洗原始列表但返回None
的列表
>>> 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]]
和使用shuffle的列表理解一样:
>>> 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]]
关于堆栈溢出的许多问题和答案已经指出,使用map或lc作为副作用是不好的做法。我想知道是否有正确的方法来使用列表理解中没有返回值的方法。
编写一个方法来包装非返回方法的唯一方法是:
>>> 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]]
>>>
答案 0 :(得分:11)
否 - 列表推导意味着与具有返回值的函数一起使用。这就是他们的语义are defined:
列表理解提供了简洁 无需求助即可创建列表的方法 使用map(),filter()和/或 拉姆达。结果列表定义 往往比列表更清晰 使用这些结构构建。每 列表理解包括一个 表达式后跟一个for子句, 然后零或更多for或if子句。 结果将是一个列表 从评估中的表达式 for和if子句的上下文 跟着它。
读过这篇文章后,应该清楚“从一个没有返回值的函数中得到列表”是一种矛盾。
只需使用for
循环“一次性”:
import random
L = []
for x in range(5):
l = range(5)
random.shuffle(l)
L.append(l)
干净简单。您的shuffled
功能也很好,可以用于列表理解。
答案 1 :(得分:8)
import random
L = [range(5) for each in xrange(5)]
for each in L:
random.shuffle(each)
<强> [编辑] 强>
OTOH你可以使用random.sample()
:
from random import sample
xr = xrange(5)
L = [sample(xr, 5) for each in xr]