如果条件为真,则合并子列表

时间:2016-12-14 14:57:22

标签: python list python-3.x merge conditional

示例:

mylist = [['2', '12/12/2016'], ['4', '10/12/2016'], ['5', '08/12/2016'], ['4', '10/12/2016'], ['7', '12/12/2016'], ['10', '12/12/2016'], ['11', '08/12/2016'], ['4', '12/12/2016'], ['10', 'test']]

子列表中的第一个元素是字符串编号
子列表中的第二个元素可以是任何字符串

如果子列表中的第一个元素已经在列表中,我想合并子列表(并删除双重的字符串)

输出:

newlist = [['2', '12/12/2016'], ['4', '10/12/2016', '12/12/2016'], ['5', '08/12/2016'], ['7', '12/12/2016'], ['10', '12/12/2016', 'test'], ['11', '08/12/2016']]

如何根据条件获得合并列表?

5 个答案:

答案 0 :(得分:6)

如果您希望将子列表中的子列表和项目的排序尽可能接近原始排序,则可以使用OrderedDict

from collections import OrderedDict

mylist = [['2', '12/12/2016'], ['4', '10/12/2016'], ['5', '08/12/2016'],
          ['4', '10/12/2016'], ['7', '12/12/2016'], ['10', '12/12/2016'],
          ['11', '08/12/2016'], ['4', '12/12/2016'], ['10', 'test']]

res = OrderedDict()
for s1, s2 in mylist:
    res.setdefault(s1, OrderedDict())[s2] = True

res = [[k] + list(v) for k, v in res.items()]
print(res)

输出:

[['2', '12/12/2016'], ['4', '10/12/2016', '12/12/2016'], ['5', '08/12/2016'], 
 ['7', '12/12/2016'], ['10', '12/12/2016', 'test'], ['11', '08/12/2016']]

上面构造OrderedDict,其中键是列表中的第一个元素,值是OrderedDict个对象。二级dicts包含列表中的第二个元素作为键。二级值无关紧要,仅使用OrderedDict,因为Python标准库没有OrderedSet

更新:假设

  1. 子列表包含第三个元素,即两个数字的列表
  2. 结果列表应根据首次出现的第一个元素
  3. 进行排序
  4. 子列表应仅包含唯一对,并根据该对的第一个数字进行排序
  5. 您可以在第二级使用set并在构造结果时对对进行排序:

    from collections import OrderedDict
    
    mylist = [['1', 'string1', [22,25]], ['4', 'string1', [12,19]], 
              ['4', 'string3', [48,53]], ['8', 'string3', [14,19]],
              ['4', 'string3', [48,53]]]
    
    res = OrderedDict()
    for s, _, l in mylist:
        res.setdefault(s, set()).add(tuple(l))
    
    res = [[k] + sorted(v) for k, v in res.items()]
    print(res)
    

    输出:

    [['1', (22, 25)], ['4', (12, 19), (48, 53)], ['8', (14, 19)]]
    

答案 1 :(得分:1)

也许你可以尝试这个代码,但不返回原来的列表:

result = [[x] + [y[1]
             for y in filter(lambda z: z[0] == x, mylist)]
      for x in set(map(lambda q: q[0], mylist))]

答案 2 :(得分:1)

这可能是一个生成器表达式,但写得很简单,这种方法应该有用......

new_list = []
for number, date in mylist:
    for index, item in enumerate(new_list):
        if item[0] == number:
            if date not in item:
                new_list[index].append(date)
            break
    else:
        new_list.append([number, date])

输出:

[['2', '12/12/2016'],
 ['4', '10/12/2016', '12/12/2016'],
 ['5', '08/12/2016'],
 ['7', '12/12/2016'],
 ['10', '12/12/2016', 'test'],
 ['11', '08/12/2016']]

尽管如上所述,OrderedDict,也许使用setdefault方法可能是一个更合适的解决方案,因为字典键是唯一的。

编辑:调整以删除重复

答案 3 :(得分:1)

作为@niemmi的替代解决方案,你可以使用它,它也使用OrderDict

from collections import OrderedDict

mylist = [['2', '12/12/2016'], ['4', '10/12/2016'], ['5', '08/12/2016'], 
['4', '10/12/2016'], ['7', '12/12/2016'], ['10', '12/12/2016'], 
['11', '08/12/2016'], ['4', '12/12/2016'], ['10', 'test']]

res = OrderedDict((key, []) for key in [tup[0] for tup in mylist])
for tup in mylist:
    if tup[1] not in res[tup[0]]:
        res[tup[0]].append(tup[1])
print(res)

答案 4 :(得分:1)

另一个常规且直截了当且易于理解的例子是:

mylist = [['2', '12/12/2016'], ['4', '10/12/2016'], ['5', '08/12/2016'], \
         ['4', '10/12/2016'], ['7', '12/12/2016'], ['10', '12/12/2016'], \
         ['11', '08/12/2016'], ['4', '12/12/2016'], ['10', 'test']]
d = dict()

for sublist in mylist:
    indx = sublist[0]
    if indx in d.keys():
        d[indx].append(sublist[1])
    else:
        d[indx] = sublist

res = []
for key,value in d.iteritems():
    res.append(value)

print sorted(res, key=lambda l: int(l[0]),reverse=False)

输出:

[['2', '12/12/2016'], ['4', '10/12/2016', '10/12/2016', '12/12/2016'], 
['5', '08/12/2016'], ['7', '12/12/2016'], ['10', '12/12/2016', 'test'], 
['11', '08/12/2016']]