0

我有类似的数据

[2, 2, 2, 2, 2, 3, 13, 113]

然后我想通过自己生成的键将其分类到单独的列表中。事实上,我想生成所有可能的列表。

一些例子:

values: [2, 2, 2, 2, 2, 3, 13, 113]
keys:   [0, 0, 1, 2, 1, 3,  3,   1]
sublists: [2, 2], [2, 2, 113], [2], [3, 13]

values: [2, 2, 2, 2, 2, 3, 13, 113]
keys:   [0, 1, 0, 0, 0, 1,  1,   0]
sublists: [2, 2, 2, 2, 113], [2, 3, 13]

values: [2, 2, 2, 2, 2, 3, 13, 113]
keys:   [2, 3, 0, 0, 4, 4,  1,   3]
sublists: [2, 2], [13], [2], [2, 113], [2, 3]

所有可能的密钥都由

def generate_keys(prime_factors):
    key_size = len(prime_factors) - 1
    key_values = [str(i) for i in range(key_size)]

    return list(itertools.combinations_with_replacement(key_values, \
        len(prime_factors)))

然后我想我可以使用键将值转移到子列表中。这就是我坚持的部分。我认为 itertools.groupby 将是我的解决方案,但经过进一步调查,我认为无法使用我的自定义列表作为 groupby 的键。

如何使用这些键将我的大列表拆分为较小的子列表?甚至可能有一种方法可以在不使用密钥的情况下做到这一点。无论哪种方式,我都不知道该怎么做,并且查看其他 Stack Overflow 问题已经在球场上,但不完全是这个问题。

4

1 回答 1

3

这可以满足您的要求:

def sift(keys, values):
    answer = collections.defaultdict(list)
    kvs = zip(keys, values)
    for k,v in kvs:
        answer[k].append(v)
    return [answer[k] for k in sorted(answer)]

In [205]: keys = [0, 0, 1, 2, 1, 3,  3,   1]

In [206]: values = [2, 2, 2, 2, 2, 3, 13, 113]

In [207]: sift(keys,values)
Out[207]: [[2, 2], [2, 2, 113], [2], [3, 13]]

说明

collections.defaultdict是一个方便dict的类,可让您定义在您尝试操作的字典中不存在键的情况下应该发生的情况。例如,在我的代码中,我有answer[k].append(v). 我们知道那append是一个list函数,所以我们知道那answer[k]应该是一个列表。但是,如果我使用的是常规的dict并且我尝试append使用不存在的键的值,我会得到KeyError如下:

In [212]: d = {}

In [213]: d[1] = []

In [214]: d
Out[214]: {1: []}

In [215]: d[1].append('one')

In [216]: d[1]
Out[216]: ['one']

In [217]: d
Out[217]: {1: ['one']}

In [218]: d[2].append('two')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/Users/USER/<ipython-input-218-cc58f739eefa> in <module>()
----> 1 d[2].append('two')

KeyError: 2

这之所以成为可能,是因为我定义了answer = collections.defaultdict(list). 如果我定义了answer = collections.defaultdict(int),我会得到一个不同的错误——它会告诉我int对象没有append方法。

zip另一方面,需要两个lists (实际上,它至少需要两个iterables),让我们调用它们list1list2返回一个元组列表,其中ith 元组包含两个对象。第一个是list1[i],第二个是list2[i]。如果list1list2的长度不等,len(zip(list1, list2))将是len(list1)和之间的较小值len(list2)(即min(len(list1), len(list2)).

压缩keysvalues后,我想创建一个字典,以便将值从映射到值keys列表values。这就是我使用 a 的原因defaultdict,这样我就不必在附加到它的值之前检查其中是否存在键。如果我使用传统的字典,我将不得不这样做:

answer = {}
kvs = zip(keys, values)
for k,v, in kvs:
    if k in answer:
        answer[k].append(v)
    else:
        answer[k] = [v]

现在您有一个dict(或类似dict对象)将值从映射keys到共享相同键的 s 列表int,您需要做的就是获取answer按排序顺序排列的值的列表,按 的键排序answersorted(answer)给我一个answer按排序顺序排列的所有 s 键的列表。

一旦我有了这个排序键列表,我所要做的就是获取它们的值,它们是整数列表,然后将所有这些列表放入一个大列表并返回该大列表。

…… 完成!希望有帮助

于 2012-10-17T00:04:13.470 回答