2016-02-13 157 views
2

我是Python的新手,目前我正在解决问题以提高我的编程技能。我碰到过一个问题,我需要从python的3 Lists中找到共同的元素,并打印出常用元素的数量。优化多个for循环

我的代码及以下步骤:

print "Enter n: " 
n = raw_input() 
print "Enter the values: " 
nlist = map(int, raw_input().split()) 
print "Enter m: " 
m = raw_input() 
print "Enter the values: " 
mlist = map(int, raw_input().split()) 
print "Enter k: " 
k = raw_input() 
print "Enter the values: " 
klist = map(int, raw_input().split()) 
plist = [] 
qlist = [] 

for x in range(0,int(n)): 
    for y in range(0,int(m)): 
     if (nlist[x]==mlist[y]): 
      plist.append(nlist[x]) 

for z in range(0,int(k)): 
    for u in range(0,len(plist)): 
     if (klist[z]==plist[u]): 
      qlist.append(klist[z]) 

print len(qlist) 

首先,我找到了共同要素的前两个Lists - nlist and mlist,并将它们存储在一个新的List - plist然后拿着第三List - klist,发现共同的元素在Lists - plist and klist并将它们添加到新的List - qlist中,并找到最终List的长度。我在想,如果Lists的长度非常高,比如说4000和两个for循环运行4000次迭代是非常耗时的,按照我的理解。那么如何优化这些问题以及解决这类问题的更好方法,以及如何使用更好的性能改进代码并在更短的时间内生成输出。请帮助我理解这一点。提前致谢。非常感谢您的帮助。

回答

2

如果您将列表作为集合存储,它们会丢失它们的顺序,但查找速度会更快,所以在这种情况下可以使用。然后,您可以使用列表理解来检查是否有任何值是其中的3个。或者,您可以使用集合交集来查找每个值,这可能会更快。

nlist = set(nlist) 
mlist = set(mlist) 
klist = set(klist) 

way1 = [i for i in nlist if i in mlist and i in klist] 
way2 = list(nlist & mlist & klist) 
+0

如果你有集合,那么十字路口似乎是一个更自然的方式来做到这一点;使用'&'运算符。另外请注意,你不能在一个集合中有重复元素。 – kwinkunks

+0

我意识到在写完第一种方法后不久,我没有添加关于重复元素的位,因为他的情况下他只需要每个值中的一个:) – Peter

+0

感谢。我会阅读关于集合并尝试实现集合的概念。 – Dev

4

看一看set.intersection

>>> nlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
>>> mlist = [1, 3, 5, 7, 9] 
>>> klist = [1, 4, 7, 10] 
>>> set(nlist).intersection(mlist) 
{1, 3, 5, 9, 7} 
>>> set(nlist).intersection(mlist).intersection(klist) 
{1, 7} 
+0

非常感谢。我完全忘了'十字路口' – Dev

2

使用套交集似乎是这里的最佳方式。

for s in list(set(list1) & set(list2) & set(list3)): 
    print s 

这将只打印常见的元素。

+0

谢谢。这帮助我了解解决这类问题的更好方法。 – Dev

+0

在这里使用集合看起来很容易,但速度很慢。你可以用numpy.array做得更好。 –