简体   繁体   English

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

[英]What is the difference between appending and assigning value to list?

When I use one-line-for loop in Python, I will got two different values depending on the process I choose(Assign and append processes). 当我在Python中使用单行循环时,根据选择的过程(分配和附加过程),我将得到两个不同的值。 I want to understand the difference and how they work. 我想了解它们的区别以及它们如何工作。 In the following two examples, I trying to write a program that returns a list that contains only the elements that are common between the lists (without duplicates). 在下面的两个示例中,我尝试编写一个程序,该程序返回一个列表,该列表仅包含列表之间的公共元素(无重复项)。

First program with append and I get the right result: 第一个带有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

After call the function and print output list: 调用函数并打印输出列表后:

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

and the output is: 输出为:

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

But when I use assign way as the following I will got the wrong answer: 但是当我如下使用分配方式时,我会得到错误的答案:

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)

and the output is: 输出为:

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

Anyone can learn me to understand How do this two different way work? 任何人都可以学习让我了解这两种不同的方式是如何工作的?

You need to break down the code into simpler form to understand it. 您需要将代码分解为更简单的形式才能理解。 Taking the first example. 以第一个例子为例。

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)

OUTPUT 输出值

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

You can see that the re_list is appending the value every time. 您可以看到re_list每次都附加值。 And the [] you have put for the first example is useless. 您在第一个示例中使用的[]是没有用的。

Coming to your second example. 来看第二个例子。 If you check the type of the expression, you would find it to be generator. 如果检查表达式的类型,则会发现它是生成器。

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

And generator expression is evaluated only when you are try to fetch the value, that explains why you are getting the duplicate 1 on this code. 只有在尝试获取值时才会对生成器表达式进行求值,这说明了为什么在此代码中得到重复的1。 Because in the expression re_list is empty when the generator is created. 因为在创建生成器时,表达式re_list为空。

Finally coming to your solution: 终于来到您的解决方案:

I trying to write a program that returns a list that contains only the elements that are common between the lists (without duplicates). 我试图编写一个返回列表的程序,该列表仅包含列表之间的公共元素(无重复项)。

You should follow Jon Clements♦ advice and implement it using a set 您应该遵循Jon Clements♦的建议,并使用一套

you should take a look at sets... eg: list(set(a).intersection(b)) 您应该看看集合...例如:list(set(a).intersection(b))

In your second example re_list is empty by the time new list is created, so val1 not in re_list is always false. 在您的第二个示例中,在创建新列表时re_list为空,因此val1 not in re_list始终为false。 In the first one you create a list of what is returned by re_list.append() ( None , as I remember) and assign it to nowhere while modifying re_list . 在第一个创建的是什么返回列表re_list.append() None ,我记得),并将其分配到任何地方,而修改re_list

By the way, why don't you use set() to obtain a list of unique elements? 顺便说一句,为什么不使用set()获得唯一元素列表?

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

is equivalent to: 等效于:

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

while the second method: 而第二种方法:

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

is equivalent to 相当于

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

It is worth to notice that with the second method you are not checking for duplicates in the final list because everytime you check the empty list while doing val1 not in re_list 值得注意的是,使用第二种方法时,您不会检查最终列表中的重复项,因为每次您在执行val1 not in re_list时都检查空列表时val1 not in re_list

Both ways work in O(n**2) time complexity, using sets : 两种方式都可以使用O(n**2)时间复杂度:

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

it's more efficient and simpler as you can do it with average time complexity O(min(len(a), len(b)) (the worst case is O(len(a)*len(b)) ). 它的效率更高,更简单,因为您可以使用平均时间复杂度O(min(len(a), len(b))最差的情况O(len(a)*len(b)) )来做到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM