将没有返回值的方法应用于列表的每个元素
有没有办法在列表理解中使用没有返回值的方法,例如 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]]
>>>
Is there a way to use methods with no return value such as random.shuffle in a 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 the for loop that applies the random.shuffle method to each item 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 map, which as a side effect shuffles the original list but returns a list of 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]]
as does using the list comprehension with 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]]
Many questions and answers on stack overflow already point out that using map or a lc for the side effect is bad practice. I was wondering if there's any correct way to use a method with no return value in a list comprehension.
Is writing a method to wrap the non-returning method the only 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]]
>>>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
无列表推导式旨在与具有返回值的函数一起使用。这就是它们的语义定义的方式:
读完本文后,应该清楚“来自没有返回值的函数的列表理解”是一个矛盾的说法。
只需使用
for
循环即可实现“一次性”的操作:干净、简单。您的
shuffled
函数也很好,并且可以用于列表理解。No - list comprehensions are meant to be use with functions having return values. It's how their semantics are defined:
Having read this, it should be clear that "a list comprehension from a function having no return value" is an oxymoron.
Just use a
for
loop for something "one off":Clean and simple. Your
shuffled
function is also just fine, and can be used in a list comprehension.伊莱说得很对。但我会选择更简洁的东西:
[edit]
OTOH,你可以使用
random.sample()
:Eli is quite right. But I'd go for something more concise:
[edit]
OTOH you could use
random.sample()
: