【问题标题】:Merge sublist if condition is true如果条件为真,则合并子列表
【发布时间】:2017-04-29 23:07:08
【问题描述】:

例子:

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']]

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

【问题讨论】:

  • 我觉得在这种情况下字典会很方便
  • 结果的顺序重要吗?
  • @niemmi,是的,订购很重要
  • 那么正确的顺序是什么?
  • defaultdict(但未排序)

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


【解决方案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))]

【讨论】:

  • 您可以通过ordered_result = sorted(result, key=lambda l: int(l[0]),reverse=False)订购result
【解决方案2】:

如果您想让子列表和子列表中的项目的顺序尽可能接近原始,您可以使用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']]

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

更新:假设

  1. 子列表具有第三个元素,即两个数字的列表
  2. 结果列表应根据第一个元素的第一次出现进行排序
  3. 子列表应仅包含唯一的对,并根据对的第一个数字进行排序

您可以在第二级使用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)]]

【讨论】:

  • 感谢您的回答。如您的答案所示,顺序是升序(按子列表的第一个元素)。
  • niemmi,我还没有完全解决我的问题。如果 mylist = [['1', 'string1', [22-25]], ['4', 'string1', [12-19]], ['4', 'string3', [48-53]], ['8', 'string3', [14-19]]] - 与我的问题中的上述相同,如果我不希望添加字符串而是添加字符串位置(字符串位置按升序排列),那么输出会是什么?预期输出:[['1', [22-25]], ['4', [12-19], [48-53]], ['8', [14-19]]]
  • @Reman [22-25] 是什么?它是包含[22, 23, 24, 25] 范围内所有整数的list 吗?子列表中的所有第三个项目是否都具有相同的类型?
  • 尼米,[22-25] ==> [startcolumn-endcolumn]
  • @Reman 开始栏和结束栏是什么?你能给出输入和预期输出的文字例子吗?除非输入为[['1', 'string1', [-3]],...],输出分别为[['1', [-3]], ...]
【解决方案3】:

这可能可以做成一个生成器表达式,但简单地写出来,这种方法应该可以工作......

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 方法可能是更合适的解决方案,因为字典键是唯一的。

编辑:调整以删除重复

【讨论】:

    【解决方案4】:

    作为@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)
    

    【讨论】:

      【解决方案5】:

      另一个常规、直接且易于理解的示例是:

      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']]
      

      【讨论】:

        猜你喜欢
        • 2013-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-24
        相关资源
        最近更新 更多