如何以相同顺序随机播放多个可迭代对象?

问题描述 投票:1回答:3

我寻求一个普通的Python函数,该函数接受任意数量的可迭代对象(元组,列表,字典),然后将它们重新排序后返回以相同顺序

a = (1, 2, {3: 4}, 5)
b = [(5,6), [7,8], [9,0], [1,2]]
c = {'arrow': 5, 'knee': 'guard', 0: ('x',2)}

x, y, z = magic(a, b, c)
print(x, y, z, sep='\n')
# ({3: 4}, 1, 2)
# [[9, 0], (5, 6), [7, 8]]
# {0: ('x', 2), 'arrow': 5, 'knee': 'guard'}

该功能必须:

  1. 以相同顺序拖曳的可迭代项(请参见上文)
  2. 接受任意数量的可迭代项
  3. 保留可迭代项类型
  4. 支持任何depthtype的嵌套可迭代对象]
  5. Not
  6. 随机播放嵌套元素(例如,上面的[7,8]不会成为[8,7]
  7. 返回迭代次数最短且没有上升错误的迭代变量(请参见上文)
  8. [如果在随机播放步骤中使用Numpy,random等,则确定(例如np.random.shuffle(magic_packing)),但不能

是高级库方法(使用多重处理,编码等-应该为“普通”)
我见过related SO's,但无法使它们适应这样的一般情况。如何做到这一点?

EDIT

:显然,我安排这则帖子的时间很差,无法被建设性的用户查看。我要求主持人删除此问题。

EDIT2

:如果这个问题很快就不会被删除,对于新读者:我已经有了答案,只是在激发好奇心和其他尝试。是的,有可能,使用6行(没有技巧,例如;),并且在Python 3.7中完全可用,而在3.6-中则部分可用(无字典)。

我寻求一个普通的Python函数,该函数接受任意数量的可迭代对象(元组,列表,字典),并以相同的顺序将它们重新排序:a =(1、2,{3:4},5)b = [ (5,6),[7,8],[9,0],...

python random python-3.7 iterable
3个回答
2
投票

这是基本方法:


0
投票
import random

a = (1, 2, {3: 4}, 5)
b = [(5,6), [7,8], [9,0], [1,2]]
c = {'arrow': 5, 'knee': 'guard', 0: ('x',2)}

def magic(*x):
    out = []
    # 6. length of shortest iterable
    min_len = min(len(a_org) for a_org in x)
    for a_org in x:
        if isinstance(a_org, list) or isinstance(a_org, tuple):
            indices = list(range(len(a_org)))
            random.shuffle(indices)
            a_copy = type(a_org)(a_org[i] for i in indices[:min_len])
        elif isinstance(a_org, dict):
            indices = list(a_org.keys())
            random.shuffle(indices)
            a_copy = {i:a_org[i] for i in indices[:min_len]}
        else:
            raise "not supported type"

        out.append(a_copy)
    return tuple(out)

print(magic(a, b, c))

0
投票
def ordered_shuffle(*iters):
    iters_types = [type(_iter) for _iter in iters]                                  # [1]
    _iters      = [x if type(x)!=dict else x.items() for x in iters]                # [2]
    iters_split = [x if type(x)!=dict else tuple(x.items()) for x in zip(*_iters)]  # [3]
    iters_shuffled = random.sample(iters_split, len(iters_split))                   # [4]
    iters_shuffled = map(tuple, zip(*iters_split))                                  # [5]
    return tuple([iters_types[i](_iter) for i, _iter in enumerate(iters_shuffled)]) # [6]
© www.soinside.com 2019 - 2024. All rights reserved.