Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过相等的第一个字段合并/分组/部分合并列表列表,以字符串形式连接第二个字段,并在其他字段中写入相同的数据_Python_Algorithm_List_Grouping - Fatal编程技术网

Python 通过相等的第一个字段合并/分组/部分合并列表列表,以字符串形式连接第二个字段,并在其他字段中写入相同的数据

Python 通过相等的第一个字段合并/分组/部分合并列表列表,以字符串形式连接第二个字段,并在其他字段中写入相同的数据,python,algorithm,list,grouping,Python,Algorithm,List,Grouping,例如,我有一个列表,我可以按前两个字段对其进行排序,这样就可以了: import operator list = [ ['1', '2', '3'], ['1', '5', '6'], ['2', '8', '9', '8', '17'], ['2', '3', '5', '3'], ['1', '14', '89', '34', '15'], ] sorted_list = sorted(list, key=operator.itemgetter(0,

例如,我有一个列表,我可以按前两个字段对其进行排序,这样就可以了:

import operator
list = [
    ['1', '2', '3'],
    ['1', '5', '6'],
    ['2', '8', '9', '8', '17'],
    ['2', '3', '5', '3'],
    ['1', '14', '89', '34', '15'],
]
sorted_list = sorted(list, key=operator.itemgetter(0, 1))
获取:

['1', '14', '89', '34', '15']
['1', '2', '3']
['1', '5', '6']
['2', '3', '5', '3']
['2', '8', '9', '8', '17']
所以,我需要的是——按第一个字段组合这些列表,第一步是[0][0]、[0][1]、[0][2]中的“1”,然后我用逗号将第二个字段连接起来:“14:2:5”,我不在乎,我将这3个列表的哪一部分附加,所以,在“|”之后可以是:

['1', '14:2:5',| '89', '34', '15']
['1', '14:2:5',| '3']
['1', '14:2:5',| '6']
(在大多数情况下,“|”之后的数据将与第一个字段匹配)

最后,我想要的是:

['1', '14:2:5', '89', '34', '15']
['2', '3:8', '5', '3']
我目前正处于某种for循环中,并一直在获取indexer:-( 我觉得这应该是一种更简单的pythonic方法。 还不知道如何找到这个算法以及它是如何调用的。类似列表列表的东西减少了映射收缩规范化元素,通过元素值附加另一个


非常感谢您的帮助,python中的事情仍然让我感到惊讶,从所有答案来看,python 3最终可以做到多么酷:

# -*- coding: utf-8 -*-
import operator
import itertools
from natsort import humansorted

list_to_sort = [
    ['1', 'A', '3'],
    ['1', '5', '6'],
    ['1', '1', '10', '11', '12'],
    ['t', 'S', '7', '0asdf'],
    ['2', '8', '9', '8', '17'],
    ['2', '705', '5', '3'],
    ['2', 'checks', 'df', '1'],
    ['1', '14', '89', '34', '15'],
]

sorted_list = humansorted(list_to_sort, key=operator.itemgetter(0, 1))
grouped = [list(g) for k, g in itertools.groupby(sorted_list, key=lambda x: x[0])]
out = [[gg[0][0], ':'.join([g[1] for g in gg])] + gg[0][2:] for gg in grouped]

for elem in out:
    print(elem)

一旦您对列表进行了排序,以便第一个字段组是连续的,您就可以使用来完成繁重的工作:

>>> grouped = [list(g) for k,g in groupby(sorted_list, key=lambda x: x[0])]
>>> grouped
[[['1', '14', '89', '34', '15'], ['1', '2', '3'], ['1', '5', '6']], [['2', '3', '5', '3'], ['2', '8', '9', '8', '17']]]
>>> out = [[gg[0][0], ':'.join([g[1] for g in gg])] + gg[0][2:] for gg in grouped]
>>> out
[['1', '14:2:5', '89', '34', '15'], ['2', '3:8', '5', '3']]

您可以使用字典来保留带有公共第一项的子列表,然后使用带有
zip
join
的列表理解来创建所需的结果:

>>> d={}
>>> 
>>> for i,*j in sorted_list:
...    d.setdefault(i,[]).append(iter(j))
... 

>>> [[i,':'.join(next(zip(*j)))]+next(j)[1:] for i,j in d.items()]
[['1', '14:2:5', '89', '34', '15'], ['2', '3:8', '5', '3']]
但请注意,此代码是用python 3编写的。如果您使用的是python 2,则可以使用
itertools.izip
而不是
zip
,要创建字典,可以执行以下操作:

>>> for i in sorted_list:
...    d.setdefault(i[0],[]).append(iter(i[1:]))

您可以使用如下所示的一对函数来完成此操作。第一个函数名为
grouper
,是一个生成器函数,当需要从流程生成中间结果时,它通常非常有用,因为在返回多个中间结果之前,需要进行大量的初始化和/或内务处理

正如@Ashwini Chaudhary在一篇评论中指出的那样,您在代码中是按照字典顺序而不是数字顺序对字段进行排序的,所以这个问题也得到了纠正

import operator

def grouper(a_list):
    if a_list:
        sorted_list = sorted(a_list,
                             key=lambda e, get_items=operator.itemgetter(0, 1):
                                map(int, get_items(e)))
        g = [sorted_list[0]]
        for x in sorted_list[1:]:
            if x[0] == g[-1][0]:
                g.append(x)
            else:
                yield g
                g = [x]
        yield g

def combiner(a_list):
    return [[g[0][0], ':'.join(e[1] for e in g)] + g[0][2:]
                for g in grouper(a_list)]

a_list = [
    ['1', '2', '3'],
    ['1', '1', '10', '11', '12'],  # element added to test sorting
    ['1', '5', '6'],
    ['2', '8', '9', '8', '17'],
    ['2', '3', '5', '3'],
    ['1', '14', '89', '34', '15'],
]

print(combiner(a_list))
输出:

['1','1:2:5:14','10','11','12',['2','3:8','5','3']]

不确定您是否意识到了这一点,但通过使用简单的
运算符。itemgetter(0,1))
您是在按字典顺序比较这些项目,而不是按它们的实际数字值。是的,也注意到了这一点,因为在本例中,排序列表中“14”位于“2”之前,在本例中,我可以接受,因为它实际上是字符串列表。还发现了一个名为的库,它以更“人性化”的方式进行排序。还发现,我不应该用'list'标识符命名列表,因为它内置于word:-)哇,我现在需要去阅读所有关于itertools的内容!谢谢