【问题标题】:Extracting a random sublist from a list in Python从 Python 中的列表中提取随机子列表
【发布时间】:2015-11-25 06:38:43
【问题描述】:

我有一个python字典如下:

{'APPLE_PROVIDERS' : ["some", "provider","can","be", "null"],
  ....
}

我想要做的是从键的列表(这是一个值)中获取一个随机子列表。不仅仅是一个元素,而是一个完全随机的子列表。这是我尝试过的:

a_list = a_dict.get('APPLE_PROVIDERS', "")
for item in a_list[randrange(0,len(a_list)) : randrange(0,len(a_list))]:
  ...do something.. 

这东西有两个问题:

  1. 如果列表为空,或者 dict 查找失败,程序将失败,因为 randrange 有 (0,0) 作为参数,这会导致错误

  2. 很多时候,两个 randrange() 调用都会生成相同的数字,尤其是当列表很小时。这将返回一个空列表。例如 a_list[5:5]

那么,处理上述情况的随机子列表的最佳方法是什么?另外,我不在乎订购。什么都行。每次for循环开始时,我只想要一个完全随机的0,1 ...直到len(a_list)元素的子列表。

如果列表可以在其他可以包含类似元素的数据结构中进行更改,那也适用于我。

【问题讨论】:

  • 明确一点:您想要从原始列表中随机选择的连续元素序列?
  • 在你的随机子列表中,会不会有重复的元素?你的随机子列表应该是多长?

标签: python random sublist


【解决方案1】:

取样。

>>> random.sample(["some", "provider", "can", "be", "null"], 3)
['some', 'can', 'provider']
>>> random.sample(["some", "provider", "can", "be", "null"], 3)
['can', 'null', 'provider']
>>> random.sample(["some", "provider", "can", "be", "null"], 3)
['null', 'some', 'provider']

【讨论】:

  • 我想要一个 0,1,2,3..len-1 个元素的子列表,而不仅仅是一个特定的数字..
  • 您是否尝试将号码替换为其他号码?
  • @user775093,您需要“公平”分发吗?
  • 公平是没有必要的。我明白了伊格纳西奥的暗示。在循环之前做一个样本,il随机改变第二个参数,绑定到列表的长度。但这会给出一个不按顺序排列的子列表吗?还是我每次都需要洗牌?例如。我想有一个相反顺序的子列表..
【解决方案2】:
>>> from random import randint
>>> left = randint(0, len(L))
>>> right = randint(left, len(L))
>>> L[left:right]
['null']

如果您不希望出现空列表

>>> left = randint(0, len(L) - 1)
>>> right = randint(left + 1, len(L))

【讨论】:

  • 但这不会是随机的。您将始终获得与原始列表顺序相同的子列表。如果我正确理解了这个问题,您应该也可以得到一个不按顺序排列的列表。
  • @GamesBrainiac,给出的示例代码正在尝试获取切片。问题似乎是切片经常是空的(因为切片的两端是颠倒的)
【解决方案3】:

Ignacio's answer 很棒。如果你想对你的代码做最少的修改,你可以这样做:

a_list = a_dict.get('APPLE_PROVIDERS', "")
if len(a_list) > 1:
    index1 = randrange(0,len(a_list)-1)
    index2 = randrange(index1+1,len(a_list))
    for item in a_list[index1:index2]:
        pass #do stuff

我在这里做了两件事:1) 我检查 a_list 是否有多个元素,以及 2) 我使用 randrange 生成索引,但是以这样的方式保证第二个大于第一个。

【讨论】:

  • if len(a_list) 可以简单地为if a_list(为您节省了len() 电话)。我还建议将此作为生成器函数(将 pass 替换为 yield item)。
  • if a_list 等价于if len(a_list) > 0,两者不一样。 pass 是否应该是 yield 取决于 OP 想要做什么。
  • @elendia-starman:啊,对不起,我在精神上跨过了> 1。并且生成器更加pythonic,特别是考虑到问题中的用例。
【解决方案4】:

因此,假设您希望在获得空列表时返回一个空列表,这里有一个示例解决方案:

from random import shuffle

def get_random_sublist(the_dict, key, number):
    l = the_dict.get(key, [])
    shuffle(l)
    return l[:number]

所以,我会使用random.shuffle。这让我可以避免要求子列表大于我们获得的实际列表的问题。

>>> DICT = {'a' : "1 2 3 4 5".split(), 'b': [], 'c': [1]}
>>> get_random_sublist(DICT, 'a', 3)
['4', '1', '2']
>>> get_random_sublist(DICT, 'b', 10)
[]

【讨论】:

    猜你喜欢
    • 2014-06-20
    • 2021-06-10
    • 2013-01-13
    • 2020-11-19
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多