IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 如何从一个已经加权重的集合中随机返回一条数据 -> 正文阅读

[Python知识库]如何从一个已经加权重的集合中随机返回一条数据

如何从一个已经加权重的集合中随机返回一条数据

一.背景

每周的周一早上都是摸鱼的,今天下午的时候我又在摸鱼中(学习),当我摸的正得劲的时候,突然背后站了一个人,然后来了一句,小明有个需求需要你来做一下,然后我肯定是细心听讲,大概的事情是这样的,我司有一个python做的爬虫系统专门用来爬取数据然后回推给内部的业务集群,调用方式是通过http接口的方式调用的,有两种方式,一种是直接访问域名,还有一种是通过ip访问,通过ip访问,这里主要说的是通过ip访问,原先系统会从配置中读取一个集合,集合中存放的是ip,然后通过随机集合长度的方式来进行负载均衡,说实话这种方式比较low,现在的场景是这样的,原先我们公司的服务都是部署在自己云服务器上的,最近在和友商合作,准备部署一些服务到友商的服务中,但是如果全部部署过去的话又怕他妈的机器扛不住影响到我们,所以就准备做一个类似权重的分流,说的简单点,就是切一部分流量到友商的机器上,然而更狗血的是ip的格式需要配置成这种格式 ip-云服务商-权重值,问了下为啥不用json,得到的回答是不想改另外一个系统。那就只能硬着头皮做了。

二.过程

首先就是把这个问题转换一下,就是从一个已经绑定权重的集合中随机根据权重获取一条数据,然后当然就是google了,google了好一会都没有查到有用的结果,然后就转换查询条件,然后查出了一段代码

import random


def weighted_choice(weights):
    totals = []
    running_total = 0

    for w in weights:
        running_total += w
        totals.append(running_total)

    rnd = random.random() * running_total
    for i, total in enumerate(totals):
        if rnd < total:
            return i


if __name__ == '__main__':
    for i in range(500):
        print(weighted_choice([2, 3, 5, 5, 5]))

上述方法主要做的是什么呢,首先传入权重的集合,遍历集合中的元素,对权重进行相加后加入到一个列表中,然后调用随机数函数在这个权重的总和之间随机生成一个处于最大权重范围内的权重值,然后遍历原先相加的权重获取到下标索引,其实我理解的是,本身列表中的数据是无序的,先按列表中的数据进行排序,然后取每个数据的权重值相加存放到另外一个列表中,此时就多了一个权重列表的数据和你原生数据的一个映射,本身权重列表中的数据的最大值使我们的取值范围,通过随机函数生成后,遍历权重列表进行比较可以得到一个下标,这个下标和我们原生的数据的下标是映射起来的,这样就能获取到我们想要的数据了。其实就相当于我们从一个列表中找出一个处于指定范围的数据的下标。上述代码其实比较的时候可以改成二分查找,可以提升效率。

import bisect
import random
from itertools import accumulate


class WeightedRandomGenerator(object):
    def __init__(self, weights):
        #遍历weights列表中的每一项相加并加入列表中
        self.totals = list(accumulate(weights))

    def next(self):
        #生成随机处于最大权重范围内的权重
        rnd = random.random() * self.totals[-1]
        #利用工具类二分查找
        return bisect.bisect_right(self.totals, rnd)

三.应用到实际场景

这里就简单讲一下怎么将这个工具类使用到我的实际场景中,首先我会从配置中读取到数据然后对数据进行切割,然后以每个ip后面的权重按从小到大排序,然后创建一个WeghtedRandomGenerator对象,然后传入后获取到下标值,然后获取原生列表中的ip发起请求。大概思路是这样的,具体业务场景具体分析。

四.总结

简单记录,不会就谷歌,每天进步一点,一年就不知道进步多少了。睡觉。

参考

https://eli.thegreenplace.net/2010/01/22/weighted-random-generation-in-python/

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:34:38  更:2021-11-30 15:34:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:37:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码