根据单独的"键"中的值合并列表。名单

时间:2018-06-12 07:20:49

标签: python python-3.x nested-lists

我有一个如下列表:

test = [[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7], [4, 6, 3, 2, 4, 5, 3, 5], [5, 3, 2, 4], [4, 3, 5, 2, 6]]

和另一个列表key,描述了原始列表需要如何合并:

key = ["one", "two", "one", "two"]

我希望将" one" s合并,并将"两个" s合并到原始test列表中。

输出应如下所示:

[[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7, 5, 3, 2, 4], [4, 6, 3, 2, 4, 5, 3, 5, 4, 3, 5, 2, 6]]

如何做到这一点?

5 个答案:

答案 0 :(得分:4)

我认为字典是最合适的解决方案。字典允许您轻松跟踪哪个分区与哪个密钥相关联。如果您只使用带有值的列表,则可能更难将分区映射到键。

以下是使用 collections.defaultdict

的解决方案
dct = defaultdict(list)

for i, e in enumerate(key):
  dct[e].extend(test[i])

# defaultdict(list,
#        {'one': [2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7, 5, 3, 2, 4],
#         'two': [4, 6, 3, 2, 4, 5, 3, 5, 4, 3, 5, 2, 6]})

# If you want the values
print(list(dct.values()))

输出:

[[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7, 5, 3, 2, 4], [4, 6, 3, 2, 4, 5, 3, 5, 4, 3, 5, 2, 6]]

答案 1 :(得分:2)

我建议你在结果列表中给出以下答案没有任何导入保持键的顺序。这在执行时间方面没有优化,但易于阅读。另请注意,如果列表keytest的长度不同,则算法将以最短的长度运行,而不会引发任何错误(zip的行为):

test = [[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7], [4, 6, 3, 2, 4, 5, 3, 5], [5, 3, 2, 4], [4, 3, 5, 2, 6]]
key = ["one", "two", "one", "two"]

d = {}
orderedKeys = []

for k,t in zip(key,test):
    if k in d.keys():
        d[k] += t
    else:
        d[k] = t
        orderedKeys.append(k)


print([d[k] for k in orderedKeys])
# [[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7, 5, 3, 2, 4], [4, 6, 3, 2, 4, 5, 3, 5, 4, 3, 5, 2, 6]]

答案 2 :(得分:1)

你可以:

  • zip()将创建[(first, second), ...]的两个列表,其中first来自keysecond是您想要分组的值
  • sorted()
  • 上的排序(first
  • itertools.groupby()
  • 上的小组(first
  • 展平(itertools.chain.from_iterable()second

e.g:

In []:
import operator as op
import itertools as it

first, second = op.itemgetter(0), op.itemgetter(1)
[list(it.chain.from_iterable(map(second, g)))
 for k, g in it.groupby(sorted(zip(key, test), key=first), first)]

Out[]:
[[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7, 5, 3, 2, 4], [4, 6, 3, 2, 4, 5, 3, 5, 4, 3, 5, 2, 6]]

答案 3 :(得分:0)

可扩展的香草解决方案:

此解决方案不会导入任何内容。

#all_keys is complete and ordered
all_keys = ["one","two","three","four","five","six","seven","eight","nine"]
max_keys = len(all_keys)

output =[[]*max_keys]

test = [[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7], [4, 6, 3, 2, 4, 5, 3, 5], [5, 3, 2, 4], [4, 3, 5, 2, 6]]
key = ["one", "two", "one", "two"]

for i,entry in enumerate(test):
    output[all_keys.index(key[i])]+=entry

答案 4 :(得分:0)

我建议这个解决方案:

test = [[2, 4, 2, 4, 3, 5, 6, 6, 3, 2, 3, 3, 3, 7], 
        [4, 6, 3, 2, 4, 5, 3, 5], 
        [5, 3, 2, 4], 
        [4, 3, 5, 2, 6]]
key = ["one", "two", "one", "two"]
if len(test) != len(key):
    raise Exception
else:
unique = list(set(key))
total = []
for x in unique:
    pair = (x, [])
    total.append(pair)
for i in range(len(key)):
    s = (key[i], test[i])
    for i in range(len(total)):
        if total[i][0] == s[0]:
            total[i] = tuple([total[i][0],total[i][1]+s[1]])

首先我使用set来避免重复的值进入keys列表,一旦我有唯一的值迭代两者,然后我创建一个由(key, array_value)组成的元组并找到我的总数组在哪里附加块。