python – 随机拆分列表,将原始订单保留在新列表中
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 随机拆分列表,将原始订单保留在新列表中,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2636字,纯文字阅读大概需要4分钟。
内容图文
![python – 随机拆分列表,将原始订单保留在新列表中](/upload/InfoBanner/zyjiaocheng/761/5f8d386872fe43738c7d072ebc2b21ee.jpg)
我很难制定我的问题所以我只是举例说明.
x = ['abc', 'c', 'w', 't', '3']
a, b = random_split(x, 3) # first list should be length 3
# e.g. a => ['abc', 'w', 't']
# e.g. b => ['c', '3']
是否有一种简单的方法可以将列表拆分为两个随机样本,同时保持原始排序?
编辑:我知道我可以使用random.sample然后重新排序,但我希望有一个简单,简单的单行方法.
编辑2:这是另一种解决方案,看看你是否可以改进它:
def random_split(l, a_size):
a, b = [], []
m = len(l)
which = ([a] * a_size) + ([b] * (m - a_size))
random.shuffle(which)
for array, sample in zip(which, l):
array.append(sample)
return a, b
编辑3:我对避免排序的担心是在最好的情况下它是O(N * log(N)).应该可以得到一个可以扩展O(N)的函数.不幸的是,到目前为止发布的解决方案都没有实际达到O(N).虽然经过一番思考后我找到了一个可行的,并且与@ PedroWerneck的性能答案相当.虽然,我不是百分百肯定这是真正的随机.
def random_split(items, size):
n = len(items)
a, b = [], []
for item in items:
if size > 0 and random.random() < float(size)/n:
b.append(item)
size -= 1
else:
a.append(item)
n -= 1
return a, b
解决方法:
我相信在拆分后不可能进行限制和排序,同时保持随机性的方式比采样和重新排序更简单.
如果没有限制,那么RNG可以通过遍历列表并随机选择将值发送到的目的地列表来随机选择:
>>> import random
>>> x = range(20)
>>> a = []
>>> b = []
>>> for v in x:
... random.choice((a, b)).append(v)
...
>>> a
[0, 2, 3, 4, 6, 7, 10, 12, 15, 17]
>>> b
[1, 5, 8, 9, 11, 13, 14, 16, 18, 19]
如果您可以处理某些偏差,则可以在达到限制时停止附加到第一个列表,并仍使用上述解决方案.如果您将处理示例中的小列表,那么在您获得第一个列表长度之前重试它应该不是什么大问题.
如果您希望它非常随机并且能够限制第一个列表大小,那么您将不得不放弃并重新排序至少一个列表.我认为最接近单线程实现的是:
>>> x = range(20)
>>> b = x[:]
>>> a = sorted([b.pop(b.index(random.choice(b))) for n in xrange(limit)])
>>> a
[0, 1, 5, 10, 15, 16, 17]
>>> b
[2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 18, 19]
你必须对a进行排序,但是b保留了顺序.
编辑
现在,你真的必须不惜一切代价避免重新排序吗?发布了许多简洁的解决方案,您的第二个解决方案非常好,但没有一个比以下更简单,更容易和更短:
def random_split(items, size):
sample = set(random.sample(items, size))
return sorted(sample), sorted(set(items) - sample)
即使考虑到两种排序操作,我认为为了简单和高效,很难击败那种.考虑优化的Python的Timsort是如何优化的,以及大多数其他方法如何为每个列表至少迭代n个项目一次.
如果你真的必须避免重新排序,我想这个也可以工作,非常简单,但迭代两次:
def random_split(items, size):
sample = set(random.sample(items, size))
a = [x for x in items if x in sample]
b = [x for x in items if x not in sample]
return a, b
这与Hexparrot的解决方案基本相同,发送者建议使用set(样本)进行比较O(1),并删除冗余索引样本并枚举调用.如果只处理可散列对象,则不需要它.
内容总结
以上是互联网集市为您收集整理的python – 随机拆分列表,将原始订单保留在新列表中全部内容,希望文章能够帮你解决python – 随机拆分列表,将原始订单保留在新列表中所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。