将没有返回值的方法应用于列表的每个元素

DTi*_*ing 9 python list-comprehension

有没有办法在列表推导中使用没有返回值的方法,例如random.shuffle?

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

这是将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]]
Run Code Online (Sandbox Code Playgroud)

我可以使用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]]
Run Code Online (Sandbox Code Playgroud)

和shuffle一样使用list comprehension:

>>> 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]]
Run Code Online (Sandbox Code Playgroud)

关于堆栈溢出的许多问题和答案已经指出,使用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]]
>>> 
Run Code Online (Sandbox Code Playgroud)

Eli*_*sky 11

否 - 列表推导意味着与具有返回值的函数一起使用.它是如何定义它们的语义:

列表推导提供了一种简洁的方法来创建列表而无需使用map(),filter()和/或lambda.结果列表定义往往比使用这些结构构建的列表更清晰.每个列表推导由一个表达式后跟一个for子句,然后是零个或多个for或if子句组成.结果将是通过在其后面的for和if子句的上下文中评估表达式而得到的列表.

阅读本文后,应该清楚"从没有返回值的函数中获得列表"是一种矛盾.

只需使用for循环"一次性":

import random
L = []
for x in range(5):
  l = range(5)
  random.shuffle(l)
  L.append(l)
Run Code Online (Sandbox Code Playgroud)

干净简单.你的shuffled功能也很好,可以用于列表理解.


pil*_*her 8

Eli是对的.但我会更简洁一些:

import random

L = [range(5) for each in xrange(5)]
for each in L:
    random.shuffle(each)
Run Code Online (Sandbox Code Playgroud)

[编辑]

OTOH你可以使用random.sample():

from random import sample

xr = xrange(5)
L = [sample(xr, 5) for each in xr]
Run Code Online (Sandbox Code Playgroud)