将值附加和分配给列表有什么区别?

时间:2018-08-30 08:35:36

标签: python python-3.x for-loop

当我在Python中使用单行循环时,根据选择的过程(分配和附加过程),我将得到两个不同的值。我想了解它们的区别以及它们如何工作。 在以下两个示例中,我试图编写一个程序,该程序返回一个列表,该列表仅包含列表之间的公共元素(无重复项)。

第一个带有append的程序,我得到正确的结果:

a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

def common_in_two_lists(list1, list2):
   re_list = []
   [re_list.append(val1) for val1 in list1 for val2 in list2 if val1==val2 and val1 not in re_list]
   return re_list

调用该函数并打印输出列表后:

l = common_in_two_lists(a, b)
print(l)

,输出为:

[1, 2, 3, 5, 8, 13]

但是当我按以下方式使用分配方式时,我会得到错误的答案:

def common_in_two_lists(list1, list2):
   re_list = []
   re_list = [val1 for val1 in list1 for val2 in list2 if val1==val2 and val1 not in re_list]
   return re_list

l = common_in_two_lists(a, b)
print(l)

,输出为:

[1, 1, 2, 3, 5, 8, 13]

任何人都可以学到我理解这两种不同方式如何工作?

3 个答案:

答案 0 :(得分:3)

您需要将代码分解为更简单的形式才能理解。 以第一个例子为例。

a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]


def common_in_two_lists1(list1, list2):
    re_list = []
    for val1 in list1:
        for val2 in list2:
            if val1 == val2 and val1 not in re_list:
                re_list.append(val1)
                print(re_list)
    return re_list


l = common_in_two_lists1(a, b)

输出

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 5]
[1, 2, 3, 5, 8]
[1, 2, 3, 5, 8, 13]

您可以看到re_list每次都附加值。您在第一个示例中输入的[]是没有用的。

第二个例子。如果检查表达式的类型,则会发现它是生成器。

re_list = print(type(val1 for val1 in list1 for val2 in list2 if val1 == val2 and val1 not in re_list))
<class 'generator'>

仅当您尝试获取值时,才会对生成器表达式进行求值,这解释了为什么在此代码中得到重复的1。因为创建生成器时表达式re_list为空。

最后找到您的解决方案:

我试图编写一个返回列表的程序,该列表仅包含列表之间的公共元素(无重复)。

您应该遵循乔恩·克莱门茨(Jon Clements)的建议,并使用一套建议来实施

  

您应该看一下集合...,例如:list(set(a).intersection(b))

答案 1 :(得分:2)

在第二个示例中,在创建新列表时re_list为空,因此val1 not in re_list始终为false。在第一个示例中,您将创建re_list.append()返回的列表(我记得还记得None),并在修改re_list时将其分配到任何地方。

顺便问一下,为什么不使用set()来获取唯一元素列表?

答案 2 :(得分:1)

def common_in_two_lists(list1, list2):
   re_list = []
   [re_list.append(val1) for val1 in list1 for val2 in list2 if val1==val2 and val1 not in re_list]
   return re_list

等效于:

def common_in_two_lists(list1, list2):
   re_list = []
   for val1 in list1:
       for val2 in list2:
          if val1==val2 and val1 not in re_list:
             re_list.append(val1)
   return re_list

第二种方法:

def common_in_two_lists(list1, list2):
   re_list = []
   re_list = [val1 for val1 in list1 for val2 in list2 if val1==val2 and val1 not in re_list]
   return re_list

等同于

def common_in_two_lists(list1, list2):
    re_list_old = []
    re_list = []
    for val1 in list1:
        for val2 in list2:
            if val1==val2 and val1 not in re_list_old: #note re_list_old here
                re_list.append(val1)
    return re_list

值得注意的是,使用第二种方法时,您不会检查最终列表中的重复项,因为每次执行val1 not in re_list

时都要检查空白列表

这两种方法都可以使用集合以O(n**2)的时间复杂度工作:

l = list(set(a) & set(b))

通过平均时间复杂度O(min(len(a), len(b))worst caseO(len(a)*len(b))),您可以更高效,更简单地