2016-12-14 33 views
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']] 

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

我要合并的子列表如果在子列表中的第一个元素是已在列表中(并删除谁是双弦)

输出:

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

我觉得在这种情况下字典会很方便 – depperm

+0

结果的排序是否重要? – niemmi

+0

@niemmi,是的订购事项 – Reman

回答

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

以上construc ts 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)]] 
+0

感谢您的回答。顺序是升序(通过子列表的第一个元素),如你的答案。 – Reman

+0

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

+0

@ Reman什么是[22-25]?它是一个'list',它包含'[22,23,24,25]'范围内的所有整数?子列表中的所有第三项都是相同类型的吗? – niemmi

1

也许你可以试试这个代码,但回报没有oredered列表:

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

您可以使用'ordered_result = sorted(result,key = lambda l:int(l [0]),reverse = False'命令'result'' –

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

编辑:调整以去除DUP的

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