算法:如何在没有单独数字的情况下将列表数据拆分为固定大小的子列表

如何解决算法:如何在没有单独数字的情况下将列表数据拆分为固定大小的子列表

我有一个算法问题要问你。不需要应用上下文,我直接举个例子。

这是一个可能的输入:input = [ 1,1,2,3,4,4 ]。 让我们假设批量大小为 5。 这里的想法是输出最大大小为 5 的列表而没有单独的数字,简而言之:2 个相同的数字不能在单独的子列表中。 示例输出:[ [1,1],[2,2],[3,4] ]

假设:数字总是排序的,batch_size 总是大于可能的数字数量

你有比我刚刚找到的更优雅的解决方案吗?

i = 0
batch_size = 5
res = []
while i < len(input):
    # Retrieve the data list according to the batch size
    data = input[i: i + size]
    # Increment the index
    i += size
    # See what's the next output looks like
    future_data = input[i: i + size]
    if future_data and future_data[0] == data[-1]:
        # So we count how many times this number appears in our current list 
        # and subtract that from our index
        cp = data.count(data[-1])
        i -= cp
        # Then remove from the current list all occurrence of that number
        data = data[:-cp]
    res.append(data)

编辑:根据@juanpa.arrivillaga 的回答:

感谢大家的反应和回答。

我继续第 2 集,我在这里给了您我的简化问题,我认为您的解决方案就足够了,尽管您做出了回应,但实际上我不知道如何将 @juanpa.arrivillaga 的解决方案调整为我的数据格式输入看起来更像:

input = { 
    'data_1' : { 
        'id': [1,4],'char': ['A','B','C','D','E','F','G','H','I','J','K','L'] 
    }
}

!'id' 和 'char' 值中的列表大小必须相等!

输出必须如下所示:

[ 
    [1,'A','C'],'G'],'L'] 
]

我知道数据结构不是最佳的,不幸的是我没有掌握它,因此无法更改...

仍然和以前一样约束(批量大小只对 id 起作用,我够清楚了吗?)

解决方法

这是我一次性完成的方法:

>>> import itertools
>>> batch_size = 5
>>> result = [[]]
>>> input_data = [ 1,1,2,3,4,4 ]
>>> for _,g in itertools.groupby(input_data):
...     current = list(g)
...     if len(result[-1]) + len(current) <= batch_size:
...         result[-1].extend(current)
...     else:
...         result.append(current)
...
>>> result
[[1,1],[2,3],[4,4]]

让我们将其分解为中间步骤以帮助理解,首先,这就是 itertools.groupby 热切评估的内容:

>>> import itertools
>>> batch_size = 5
>>> grouped = [list(g) for k,g in itertools.groupby([ 1,4 ])]
>>> grouped
[[1,2],[3,4]]

然后,只需建立您的结果,即子列表列表。如果它可以放入当前子列表中,则将该组添加到子列表中,否则,追加一个由该组组成的新子列表(我们可以假设它不大于​​batch_size):

>>> result = [[]]
>>> for group in grouped:
...     if len(result[-1]) + len(group) <= batch_size:
...         result[-1].extend(group)
...     else:
...         result.append(group[:])
...
>>> result
[[1,4]]

上面对数据进行了两次传递,发布的第一个示例进行了一次传递。

请注意,如果使用 itertools.groupby 感觉像是“作弊”,您可以实现一些相对容易的方法:

def simple_groupby(data):
    it = iter(data)
    empty = object()
    current = next(it,empty)
    if current is empty:
        return
    prev = current
    acc = [current]
    for current in it:
        if prev == current:
            acc.append(current)
        else:
            yield acc
            acc = [current]
        prev = current
    yield acc
,

您可以将 itertools.groupby 与递归生成器函数结合使用,以查找符合您条件的可能合并。这样,您可以更好地处理更模棱两可的情况,其中不清楚哪个“兄弟”组应该吸收双配对和/或截断结果,其中组的长度大于 batch_size:

from itertools import groupby
data = {'data_1': {'id': [1,4],'char': ['A','B','C','D','E','F','G','H','I','J','K','L']}}
batch_size = 5
def get_groups(d,c = [],p = []):
  if not d and not p and all((l:=len(i)) <= batch_size and i and l != 2 for i in c):
     #found valid combo
     yield c
  elif d:
     _p = (k:=(p+d[0]))[(b:=(l if (l:=len(k)) <= batch_size else -1*(l-batch_size))):]
     if l == 2 and not _p:
        #if group size is two,then we have to find possible merges for group
        yield from get_groups(d[1:],c=c,p = k)
        yield from get_groups([c[-1]+k]+d[1:],c=c[:-1],p = [])
     elif _p:
        #group size > batch_size,need to find possible siblings that can take subgroups of groups
        for i in range(batch_size):
           yield from get_groups(d[1:],c=c+[k[:i]],p = k[i:])
           if c and len(c[-1]) + i <= batch_size:
              yield from get_groups(d[1:],c=c[:-1]+[c[-1]+k[batch_size:batch_size+i]]+[k[:batch_size]],p = k[batch_size+i:])
     yield from get_groups(d[1:],c=c+[k[:b]],p = _p)
  elif p:
     yield from get_groups(d[1:],c=c+[p],p = [])

combo = next(get_groups([list(b) for _,b in groupby(data['data_1']['id'])]))
c_m = iter(data['data_1']['char'])
result = [[i for j in [(x,next(c_m)) for x in y] for i in j] for y in combo]

输出:

[[1,'A','C'],'G'],'L']]
,

如果您不想使用任何库(模块),那么此解决方案适合您。

batch_size = 5
id = list(map(int,input("Enter multiple ids in one line with space between them: ").split()))
char = list(map(str,input("Enter multiple char in one line with space between them: ").split()))
id_char_input = {char[i]: id[i] for i in range(len(id))}
id_unique = list(set([value for key,value in id_char_input.items()]))
group_input = [[] for _ in range(len(id_unique))]
output = []
j = 0

for key,value in id_char_input.items():
    group_input[id_unique.index(value)].append(value)
    group_input[id_unique.index(value)].append(key)

while j < len(group_input):
    if j != len(group_input) - 1:
        if len(group_input[j] + group_input[j + 1]) <= 2*batch_size:
            output.append(group_input[j] + group_input[j + 1])
            j += 2
        else:
            if group_input[j] not in output:
                output.append(group_input[j])
            j += 1
    else:
        output.append(group_input[j])
        break

print(output)
Output:
Enter multiple ids in one line with space between them: 1 1 1 2 2 2 2 3 3 4 4 4
Enter multiple char in one line with space between them: A B C D E F G H I J K L
[[1,'L']]

编辑:现在您可以从输入中获取 id 和 char 的值。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res