我有像
这样的数据[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问题已经在球场上发挥作用,但不完全是这个问题。
答案 0 :(得分: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
需要两个list
s(实际上,它至少需要两个iterable
s),我们称之为list1
和list2
并返回一个元组列表,其中i
元组包含两个对象。第一个是list1[i]
,第二个是list2[i]
。如果list1
和list2
长度不等,则len(zip(list1, list2))
和len(list1)
中的len(list2)
值会较小(即min(len(list1), len(list2))
。
我压缩keys
和values
之后,我想创建一个dict,将keys
的值映射到values
的值列表。这就是我使用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
中的值映射到共享相同密钥的int
列表,所有您需要做的是按排序顺序获取answer
的值列表,按answer
的键排序。 sorted(answer)
以排序顺序为我提供了所有answer
个键的列表。
一旦我有了这个排序键列表,我所要做的就是获取它们的值,这些值是整数列表,并将所有这些列表放入一个大列表中并返回该大列表。
... annnnnd完成!希望有所帮助