2016-04-26 190 views
0

我最近开始学习python。 所以我写了一些小代码,这段代码要求2个大小的列表,用0-9的随机整数创建2个列表,然后吐出两个列表之间的交集。'for'循环解释请求

最后一个“for”循环 - 我遇到了麻烦,因为一开始我的“十字路口”列表有重复,然后我查找了一个答案,得到了我现在拥有的,它的工作原理,但我不知道为什么。我的问题在于如何“为我在l1和l2”工作? 我知道“因为我在范围(k)”正在经历数字0-k,但这个奇怪的循环与“和”运算符只是困惑我。

l1 = [] 
l2 = [] 
C = [] 
s1 = int(input("Your 1st list size->")) 
s2 = int(input("Your 2nd list size->")) 
for i in range(s1): 
    from random import randint 
    k = (randint(0,9)) 
    l1.append(k) 
print("First List ->" , l1) 
for i in range(s2): 
    from random import randint 
    k = (randint(0,9)) 
    l2.append(k) 
print("Second List ->" , l2) 
for i in l1 and l2: 
    if i in l1 and l2: 
     C.append(i) 

print("Intersection ->" , C) 

请让我知道是否有另一个地方提交这样的问题(如果这里不适合)。

+0

“我在l1和l2” - 这是乐观的。 – aaa90210

回答

1

此代码是非常误导的,所以这是可以理解的,你困惑。下面的代码片段是问题:

for i in l1 and l2: 
    if i in l1 and l2: 
     C.append(i) 

这实际上等同于以下内容:

for i in l2: 
    if i in l1: 
     C.append(i) 

for发言,分组是for i in (l1 and l2)。换句话说,对l1 and l2进行评估,并使用结果列表。如果l1非空,那么这只是l2。如果l1是空的,那么它是一个空列表[],但是这是有效的,因为在这种情况下,交叉点必须是空的。

if声明中,分组为if (i in l1) and l2。如果l2非空,那么如果i in l1为真,则这将是有效的。如果l2是空的,这将始终是有效的错误,但再次,这是有效的,因为在这种情况下,交叉点必须是空的。

请注意,可以通过为l1创建一个集来加速循环体。这将使在l1长度基本成员资格测试常数时间而不是线性:

s1 = set(l1) 
for i in l2: 
    if i in s1: 
     C.append(i) 

您也可以使用列表理解来获得相同的结果,分配给C,而不是追加到它:

s1 = set(l1) 
C = [i for i in l2 if i in s1] 
+0

替代方案确实使得更直观的感觉! – user313448

1

为了解for循环如何工作,我们需要检查结果l1 and l2。在Python非空容器将分别False评估布尔上下文和空容器True是:

>>> bool([]) 
False 
>>> bool([1]) 
True 

然后and运算符将返回第一个参数的情况下,它False在布尔上下文和第二在第一个参数的计算结果为True情况:

>>> [] and [1] 
[] 
>>> [2] and [1] 
[1] 

鉴于以上信息,我们后来才知道,在l2for i in l1 and l2:结果项的情况下l1正在迭代非空。如果l1为空,分别循环将不会运行一次。

在循环if i in l1 and l2:评估True万一i可以从l1发现(并l2不是空的,但执行就不会在这里结束,如果l2将不包含单个项目)。由于循环仅遍历l2上的项目并检查i是否存在于l1中,因此它将生成交集。请注意,您会得到相同的结果与下面的代码:

for i in l2: 
    if i in l1: 
     C.append(i) 

你可以为了检查set使产生交集简单得多:

>>> set([1,2,3]) & set([4,5,1]) 
set([1]) 

注意,由于集是独一无二的收藏项目结果将在情况有所不同的是l2包含同一项目的多个副本:假设两个名单是

Your 1st list size->4 
Your 2nd list size->4 
First List -> [8, 8, 0, 2] 
Second List -> [0, 4, 0, 3] 
Intersection -> [0, 0] 

>>> set([8, 8, 0, 2]) & set([0, 4, 0, 3]) 
set([0]) 
0

非空:

l1 and l2 == l2 

因此你正在写的是:

for i in l2: 
    if i in l1 and l2: 
     c.append(i) 

这是有道理的。

我会看看到蟒蛇套,如果我是你:

s1 = set(l1); s2 = set(l2) 
intersection = list(s1.intersection(s2)) 
+0

对不起,我刚开始,我不知道什么套(我肯定从数学知道)..但仍然谢谢你的答案! – user313448

+0

我想如果你刚刚开始并不重要,但将来你使用的方法会比使用集合交集方法慢。如果你有时间,请看看它们。或者你可以记住他们存在,如果你曾经试图做这样的事情再次 – user3684792