gpt4 book ai didi

python - 扩展分组代码以处理更通用的输入

转载 作者:太空宇宙 更新时间:2023-11-03 18:20:47 25 4
gpt4 key购买 nike

我需要根据键是否大于或小于给定值将 float 列表或不同长度的(命名)元组列表分组。

例如,给定一个 2 小于 1 的幂列表,以及一个截止列表:

twos = [2**(-(i+1)) for i in range(0,10)]
cutoffs = [0.5, 0.125, 0.03125]

然后函数

split_into_groups(twos, cutoffs)

应该返回

[[0.5], [0.25, 0.125], [0.0625, 0.03125], [0.015625, 0.0078125, 0.00390625, 0.001953125, 0.0009765625]]

我实现了这样的功能:

def split_by_prob(items, cutoff, groups, key=None):
for k,g in groupby(enumerate(items), lambda (j,x): x<cutoff):
groups.append((map(itemgetter(1),g)))
return groups

def split_into_groups(items, cutoffs, key=None):
groups = items
final = []
for i in cutoffs:
groups = split_by_prob(groups,i,[],key)
if len(groups) > 1:
final.append(groups[0])
groups = groups.pop()
else:
final.append(groups[0])
return final
final.append(groups)
return final

目前通过的测试是:

>>> split_by_prob(twos, 0.5, [])
[[0.5], [0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625, 0.001953125, 0.0009765625]]

>>> split_into_groups(twos, cutoffs)
[[0.5], [0.25, 0.125], [0.0625, 0.03125], [0.015625, 0.0078125, 0.00390625, 0.001953125, 0.0009765625]]
>>> split_into_groups(twos, cutoffs_p10)
[[0.5, 0.25, 0.125], [0.0625, 0.03125, 0.015625], [0.0078125, 0.00390625, 0.001953125], [0.0009765625]]

其中 cutoffs_p10 = [10**(-(i+1)) for i in range(0,5)]

我可以直接将其扩展为以下形式的元组列表

items = zip(range(0,10), twos)

通过改变

def split_by_prob(items, cutoff, groups, key=None):
for k,g in groupby(enumerate(items), lambda (j,x): x<cutoff):
groups.append((map(itemgetter(1),g)))
return groups

def split_by_prob(items, cutoff, groups, key=None):
for k,g in groupby(enumerate(items), lambda (j,x): x[1]<cutoff):
groups.append((map(itemgetter(1),g)))
return groups

如何通过添加一个默认为 float (或整数等)列表但可以处理元组和命名元组的键来扩展原始方法?

例如:

split_into_groups(items, cutoffs, key=items[0])

会返回

[[(0,0.5)], [(1,0.25), (2,0.125)], [(3,0.0625), (4,0.03125)], [(5,0.015625), (6,0.0078125), (7,0.00390625), (8,0.001953125), (9,0.0009765625)]]

最佳答案

在我的回答中,我认为截止值是按递增顺序排列在最后 - 只是为了简化情况。

鉴别器检测槽

class Discriminator(object):
def __init__(self, cutoffs):
self.cutoffs = sorted(cutoffs)
self.maxslot = len(cutoffs)
def findslot(self, num):
cutoffs = self.cutoffs
for slot, edge in enumerate(self.cutoffs):
if num < edge:
return slot
return self.maxslot

grouper 将元素放入插槽

from collections import defaultdict
def grouper(cutoffs, items, key=None):
if not key:
key = lambda itm: itm
discr = Discriminator(cutoffs)
result = defaultdict(list)
for item in items:
num = key(item)
result[discr.findslot(num)].append(item)
return result

def split_into_groups(cutoffs, numbers, key=None):
groups = grouper(cutoffs, numbers, key)
slot_ids = sorted(groups.keys())
return [groups[slot_id] for slot_id in slot_ids]

关于判别器和grouper的结论

建议的鉴别器甚至适用于未排序的项目。

关于key的结论

事实上,提供key功能比最初看起来更容易。

它只是一个通过参数提供的函数,因此它成为调用转换函数来获取值的别名,我们想用它来进行比较、分组等。

有一种特殊情况None,对于这种情况我们必须使用一些恒等函数。

最简单的是

func = lambda itm: itm

注意:上面的所有功能都通过测试套件进行了测试(包括使用 key 功能,但我从这个答案中删除了它,因为它变得太长了。

关于python - 扩展分组代码以处理更通用的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24191889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com