当我在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]
任何人都可以学到我理解这两种不同方式如何工作?
答案 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 case为O(len(a)*len(b))
),您可以更高效,更简单地