python:展平列表,同时保留某些索引的嵌套结构
python: flatten list while preserving nested structure for certain indexes
我在 Python 中找到了几篇关于 flattening/collapsing 列表的帖子,但是 none 涵盖了这种情况:
输入:
[a_key_1, a_key_2, a_value_1, a_value_2]
[b_key_1, b_key_2, b_value_1, b_value_2]
[a_key_1, a_key_2 a_value_3, a_value_4]
[a_key_1, a_key_3, a_value_5, a_value_6]
输出:
[a_key_1, a_key_2, [a_value1, a_value3], [a_value_2, a_value_4]]
[b_key_1, b_key_2, [b_value1], [b_value_2]]
[a_key_1, a_key_3, [a_value_5], [a_value_6]]
我想展平列表,以便每组唯一键只有一个条目,其余值合并到这些唯一键旁边的嵌套列表中。
编辑:输入中的前两个元素将始终是键;最后两个元素将始终是值。
这可能吗?
是的,这是可能的。这是一个执行任务的函数(使用 input/output 中的 doctest):
#!/usr/bin/env python
"""Flatten lists as per """
from collections import OrderedDict
def flatten(key_length, *args):
"""
Take lists having key elements and collect remainder into result.
>>> flatten(1,
... ['A', 'a1', 'a2'],
... ['B', 'b1', 'b2'],
... ['A', 'a3', 'a4'])
[['A', ['a1', 'a2'], ['a3', 'a4']], ['B', ['b1', 'b2']]]
>>> flatten(2,
... ['A1', 'A2', 'a1', 'a2'],
... ['B1', 'B2', 'b1', 'b2'],
... ['A1', 'A2', 'a3', 'a4'],
... ['A1', 'A3', 'a5', 'a6'])
[['A1', 'A2', ['a1', 'a2'], ['a3', 'a4']], ['B1', 'B2', ['b1', 'b2']], ['A1', 'A3', ['a5', 'a6']]]
"""
result = OrderedDict()
for vals in args:
result.setdefault(
tuple(vals[:key_length]), [],
).append(vals[key_length:])
return [
list(key) + list(vals)
for key, vals
in result.items()
]
if __name__ == '__main__':
import doctest
doctest.testmod()
(已编辑以同时处理您的原始问题和编辑后的问题)
data = [
["a_key_1", "a_key_2", "a_value_1", "a_value_2"],
["b_key_1", "b_key_2", "b_value_1", "b_value_2"],
["a_key_1", "a_key_2", "a_value_3", "a_value_4"],
["a_key_1", "a_key_3", "a_value_5", "a_value_6"],
]
from itertools import groupby
keyfunc = lambda row: (row[0], row[1])
print [
list(key) + [list(zipped) for zipped in zip(*group)[2:]]
for key, group
in groupby(sorted(data, key=keyfunc), keyfunc)
]
# => [['a_key_1', 'a_key_2', ['a_value_1', 'a_value_3'], ['a_value_2', 'a_value_4']],
# ['a_key_1', 'a_key_3', ['a_value_5'], ['a_value_6']],
# ['b_key_1', 'b_key_2', ['b_value_1'], ['b_value_2']]]
有关详细信息,请查看 Python Docs
我在 Python 中找到了几篇关于 flattening/collapsing 列表的帖子,但是 none 涵盖了这种情况:
输入:
[a_key_1, a_key_2, a_value_1, a_value_2]
[b_key_1, b_key_2, b_value_1, b_value_2]
[a_key_1, a_key_2 a_value_3, a_value_4]
[a_key_1, a_key_3, a_value_5, a_value_6]
输出:
[a_key_1, a_key_2, [a_value1, a_value3], [a_value_2, a_value_4]]
[b_key_1, b_key_2, [b_value1], [b_value_2]]
[a_key_1, a_key_3, [a_value_5], [a_value_6]]
我想展平列表,以便每组唯一键只有一个条目,其余值合并到这些唯一键旁边的嵌套列表中。
编辑:输入中的前两个元素将始终是键;最后两个元素将始终是值。
这可能吗?
是的,这是可能的。这是一个执行任务的函数(使用 input/output 中的 doctest):
#!/usr/bin/env python
"""Flatten lists as per """
from collections import OrderedDict
def flatten(key_length, *args):
"""
Take lists having key elements and collect remainder into result.
>>> flatten(1,
... ['A', 'a1', 'a2'],
... ['B', 'b1', 'b2'],
... ['A', 'a3', 'a4'])
[['A', ['a1', 'a2'], ['a3', 'a4']], ['B', ['b1', 'b2']]]
>>> flatten(2,
... ['A1', 'A2', 'a1', 'a2'],
... ['B1', 'B2', 'b1', 'b2'],
... ['A1', 'A2', 'a3', 'a4'],
... ['A1', 'A3', 'a5', 'a6'])
[['A1', 'A2', ['a1', 'a2'], ['a3', 'a4']], ['B1', 'B2', ['b1', 'b2']], ['A1', 'A3', ['a5', 'a6']]]
"""
result = OrderedDict()
for vals in args:
result.setdefault(
tuple(vals[:key_length]), [],
).append(vals[key_length:])
return [
list(key) + list(vals)
for key, vals
in result.items()
]
if __name__ == '__main__':
import doctest
doctest.testmod()
(已编辑以同时处理您的原始问题和编辑后的问题)
data = [
["a_key_1", "a_key_2", "a_value_1", "a_value_2"],
["b_key_1", "b_key_2", "b_value_1", "b_value_2"],
["a_key_1", "a_key_2", "a_value_3", "a_value_4"],
["a_key_1", "a_key_3", "a_value_5", "a_value_6"],
]
from itertools import groupby
keyfunc = lambda row: (row[0], row[1])
print [
list(key) + [list(zipped) for zipped in zip(*group)[2:]]
for key, group
in groupby(sorted(data, key=keyfunc), keyfunc)
]
# => [['a_key_1', 'a_key_2', ['a_value_1', 'a_value_3'], ['a_value_2', 'a_value_4']],
# ['a_key_1', 'a_key_3', ['a_value_5'], ['a_value_6']],
# ['b_key_1', 'b_key_2', ['b_value_1'], ['b_value_2']]]
有关详细信息,请查看 Python Docs