【问题标题】:Merge list of lists in python 3合并python 3中的列表列表
【发布时间】:2017-09-22 10:50:14
【问题描述】:

我有这 2 个列表:

list1= [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]

list2= [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

我想输出这个:

desiredlist =[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 0], ['user4', 288, 'Feb 2017', 60, 10]]

为此我有这个功能:

def mergesafirmacheta(list1,list2):
    desiredlist = []
    for id, n1, dates, n2, n3 in list1:
        counter = 0
        for list_2 in list2:
            if n1 == list_2[1]:
                desiredlist.append(list_2[:3] + [n2, list_2[4]])
            else:
                   counter += 1
                   if counter == len(list2):
                       desiredlist.append([id, n1, dates, n2, 0])
    print (desiredlist)

但这只会输出这个:

desiredlist =[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 0]]

^^ user4 丢失(检查我想要的输出),我可以从我的函数中看到为什么,我尝试在我的第一个 is 语句之后添加它:

elif list_2[1] != n1:
    desiredlist.append(list_2)

但这不起作用,这是计算所需列表的规则:

list2[1] == list1[1](示例186 == 186)附加到我的desiredlist list2[0], list2[1], list2[2], list1[3], list2[4] 时,如果list1[1] 不在list2 列表中,则更改附加到desiredlist list1[0], list1[1], list1[2], list1[3], 0, 并且如果@987654332不在list1 列表中的@ 附加到desiredlist list2[0], list2[1], list2[2], list2[3], list2[4]。这有点难以放松,但我认为检查我想要的输出和我现在实际输出的内容要容易得多。

【问题讨论】:

  • 那么所有的“值”都应该来自第二个列表?我不太清楚你是如何合并输入的。
  • 你为什么不用字典呢?
  • 从两者中,在我想要的输出中有 user3(来自 list1 的原始文件)和 user4(来自 list2 的原始文件)
  • 我很不清楚什么时候会从一个列表或另一个列表中结转一个值。例如,对于用户 1,550 取自第一个列表,740 取自第二个列表。但是对于用户 2,第二个列表的 1000 胜过第一个列表的 3579。为什么?!规则是什么?

标签: python python-3.x list


【解决方案1】:

通过更改格式,我设法做到了您的意图。我将您的所有子列表转换为 dict,并使用密钥 user

因为合并 dict 更容易,并且子列表中 user 的顺序无关紧要。

最后一步是迭代合并的dictlist1list2 并执行您的特殊操作。据我了解,是将list1 的最后一个数字与list2 合并。然后你重新创建你想要的子列表。

from itertools import chain
from collections import defaultdict

list1 = [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]
list2 = [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

# Transform list to dict with key as 'userN'
def to_dict(lst): return {x[0]: x[1:] for x in lst} 

# Now create a dict that combined list of user1..N+1
tmp_dict = defaultdict(list)
for k, v in chain(to_dict(list1).items(), to_dict(list2).items()):
  tmp_dict[k].append(v)

desired_output = []
for k, v in tmp_dict.items():
  if len(v) == 2:
    v[1][-2] = v[0][-2] # Take the before last of list1 to remplace with before last one of list2
    desired_output.append([k] + v[1])
  else:
    desired_output.append([k] + v[0])

print(desired_output)

输出:

[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 60], ['user4', 288, 'Feb 2017', 60, 10]]

编辑

看来我弄错了,您的list1 必须检查list2 的所有内容,在这种情况下,您应该先创建list2dict,然后再应用您的特定条件。例如:

from itertools import chain

list1 = [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]
list2 = [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

# Transform list to dict with key as 'userN'
def to_dict(lst): return {x[0]: x[1:] for x in lst} 

# First, transfrom list2 to dict
list2_dict = {}
for k, v in to_dict(list2).items():
  list2_dict[k] = v

# Then iterate on list1 to compare
desired_output = []
for k, v in to_dict(list1).items():
  if k in list2_dict: # key of list1 exists in list2
    list2_dict[k][-2] = v[-2] # replace value
    desired_output.append([k] + list2_dict[k]) # Then add list2
    list2_dict.pop(k) # And remove it from old dict
  else: # list1 does not exists in list2
    v[-1] = 0 # Set last element to zero
    desired_output.append([k] + v)

for k, v in list2_dict.items(): # Now add elements present only in list2
  desired_output.append([k] + v)

print(desired_output)

输出:

[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 0], ['user4', 288, 'Feb 2017', 60, 10]]

注意:我们可以去掉defaultdict,因为同一个键不会被添加两次。

【讨论】:

  • 这里 ['user3', 281, 'Mai 2017', 10, 60] 应该是:['user3', 281, 'Mai 2017', 10, 0],就像我发布的在我想要的输出中。 (如果您有一个不在 list2 列表中的 list1[1],则追加到所需列表 list1[0]、list1[1]、list1[2]、list1[3]、0)
  • @TatuBogdan,哇,这是一个棘手的条件。那么在这种情况下,您的选择将是首先将您的第二个列表转换为dict,然后尝试使用第二个列表,您可以在那之后添加特殊检查。
  • @TatuBogdan 请检查我的编辑,我试图将您的评论包含在您的“棘手”条件中
  • 工作,谢谢,我会研究代码并尝试更详细地理解它。不错,你救了我!
【解决方案2】:

使用此代码:

list1= [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]

list2= [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

final_list = []
for l1_data, l2_data in zip(list1, list2):
    if l1_data[0] == l2_data[0]:
        for index, elem in enumerate(l2_data):
            if index+1 <= len(l1_data):
                if not elem and l1_data[index]:
                    l2_data[index] = l1_data[index]                    
    else: final_list.append(l1_data)
    final_list.append(l2_data)
print final_list

输出:

[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 60], ['user4', 288, 'Feb 2017', 60, 10]]

【讨论】:

  • 我正在检查你的输出,唯一的问题是在这个列表中:['user3', 281, 'Mai 2017', 10, 60] 当你没有匹配时我想要 0像这样: ['user3', 281, 'Mai 2017', 10, 0] (我发布在我想要的输出中。
  • 如果您有一个不在 list2 中的 list1[1] 列表追加到所需列表 list1[0], list1[1], list1[2], list1[3], 0
  • 但是list2中没有包含user3的列表。这就是为什么我将它们添加到最终列表中。
  • 我明白了,它在 list1 上,当您循环检查它是否在 list1 中而不是在 list2 中然后将索引 [4] 设为 0 时,这是不可能的?
【解决方案3】:

您可以遍历两个列表组合中不同的第二个元素:

for n in set([item[1] for item in list1+list2]):

然后您可以通过在两个列表中查找 n 来决定添加到您想要的列表中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2010-11-11
    • 2017-09-05
    • 2016-04-18
    • 2014-05-16
    • 2021-02-19
    • 2017-10-26
    相关资源
    最近更新 更多