Jer*_*Sto 3 python random python-itertools python-3.x
我试图在嵌套的列表列表中随机打乱一个元素。
例如我有:
list1=[[['a', 'b', 'c', 1], ['a', 'b', 'c', 2]], [['a', 'b', 'c', 3], ['a', 'b', 'c', 4]], [['a', 'b', 'c', 5], ['a', 'b', 'c', 6]]]
Run Code Online (Sandbox Code Playgroud)
我想随机打乱每个子列表(浮点数)的第三个元素,同时保持此嵌套列表中的其余列表条目及其结构完好无损。例如:
list1=[[['a', 'b', 'c', 1], ['a', 'b', 'c', 6]], [['a', 'b', 'c', 4], ['a', 'b', 'c', 2]], [['a', 'b', 'c', 3], ['a', 'b', 'c', 5]]]
Run Code Online (Sandbox Code Playgroud)
到目前为止,我想出了以下几点:
import random
list1 = [[['a', 'b', 'c', 1], ['a', 'b', 'c', 2]], [['a', 'b', 'c', 3], ['a', 'b', 'c', 4]], [['a', 'b', 'c', 5], ['a', 'b', 'c', 6]]]
vals = [x[3] for line in list1 for x in line]
shuffled_vals = random.sample(vals,len(vals))
counter = 0
for i in range(len(list1)):
for j in range(len(list1[i])):
list1[i][j][3] = shuffled_vals[counter]
counter += 1
Run Code Online (Sandbox Code Playgroud)
尽管这符合预期,但我很好奇是否有更优雅的/Pythonic 解决方案。此外,我不确定它的扩展性如何 - 我打算使用它的列表将包含数百万个条目。
非常感谢任何改进此代码(到更 Pythonic 或更高效的代码)的提示。
你的代码对我来说看起来不错。除了我不会改变(就地修改)输入列表之外,我会做几乎相同的事情。通常,您还会避免使用range(len(X))并更喜欢X直接迭代 的元素。
把它放在一起会得到这样的东西:
from random import sample
vals = [x[3] for line in list1 for x in line]
vals = sample(vals, len(vals))
new_list = [[sub_l[:3] + [vals.pop()] for sub_l in l] for l in list1]
Run Code Online (Sandbox Code Playgroud)
在这里我也利用了,.pop()因为我们vals用完就可以扔掉。这使我免于使用像counter你那样的东西。
也许一个小的改进是在我们可以完美控制对象的情况下使用变异。random.sample()如果您想避免突变,使用非常方便,但如果您不关心,您可以简单地替换vals = sample(vals, len(vals))为random.shuffle(vals). 我觉得这里更好一些,因为它更具可读性。