我正在尝试比较Python 2.6中的两个整数列表,每个整数列表大小相同。我需要的比较是将列表1中的第一项与列表2中的第一项进行比较,将列表1中的第二项与列表2中的第二项进行比较,依此类推,如果所有列表项都跟随,则返回结果相同的比较标准。它应该表现如下:
list1 = [1,1,1,1]
list2 = [2,1,2,3]
compare(list1,list2)
# returns a "list 1 is <= list 2" response.
list1 = [4,1,4,3]
list2 = [2,1,2,3]
compare(list1,list2)
# returns a "list 1 is >= list 2" response.
list1 = [3,2,3,2]
list2 = [1,4,1,4]
compare(list1,list2)
# returns None— some items in list1 > list2, and some items in list2 > list1.
我想我可以编写类似下面的代码,但我不知道它是否最有效。我的程序将调用这个方法很多,所以我想尽可能地简化这个。
def compare(list1,list2):
gt_found = 0
lt_found = 0
for x in range(len(list1)):
if list1[x] > list2[x]:
gt_found += 1
elif list1[x] < list2[x]:
lt_found += 1
if gt_found > 0 and lt_found > 0:
return None #(some items >, some items <)
if gt_found > 0:
return 1 #(list1 >= list2)
if lt_found > 0:
return -1 #(list1 <= list2)
return 0 #(list1 == list2)
它是否已经达到了它的好处(n的大O),或者是否有更快的方法(或者使用系统功能的方式)?
澄清:我希望返回“无”的情况最常发生,所以这很重要。
答案 0 :(得分:5)
您熟悉精彩的zip
功能吗?
import itertools
def compare(xs, ys):
all_less = True
all_greater = True
for x, y in itertools.izip(xs, ys):
if not all_less and not all_greater:
return None
if x > y:
all_less = False
elif x < y:
all_greater = False
if all_less:
return "list 1 is <= list 2"
elif all_greater:
return "list 1 is >= list 2"
return None # all_greater might be set False on final iteration
Zip在这种情况下需要两个列表(xs
和ys
,但可以随意调用它们)并为一系列元组创建一个迭代器。
izip([1,2,3,4], [4,3,2,1]) == [(1,4), (2,3), (3,2), (4,1)]
通过这种方式,您可以同时迭代两个列表并串联比较每个值。时间复杂度应为O(n),其中n是列表的大小。
如果未满足&gt; =或&lt; =条件,它将提前返回。
正如 James Matta 所指出的那样,itertools.izip
的性能优于Python 2中的标准zip
。在Python 3中并非如此,其中标准{{1}按照旧版本zip
的方式工作。
答案 1 :(得分:5)
您可以考虑基于numpy的矢量化比较。
import numpy as np
a = [1,1,1,2]
b = [2,2,4,3]
all_larger = np.all(np.asarray(b) > np.asarray(a)) # true if b > a holds elementwise
print all_larger
True
显然,你可以设计得到你的答案。
all_larger = lambda b,a : np.all(np.asarray(b) > np.asarray(a))
if all_larger(b,a):
print "b > a"
elif all_larger(a,b):
print "a > b"
else
print "nothing!"
可以完成<, >, <=, >=,
等每种类型的比较。
答案 2 :(得分:0)
对于对这两种方法的表现感兴趣的人,我将迭代方法命名为“龟”&#39;和numpy方法&#39; hare&#39;,并使用下面的代码进行测试。
起初,“龟”&#39;赢了[.009s [T] vs .033s [H]],但我检查了一下,发现asarray()被调用的频率超过了它需要的频率。通过这个修复,&#39;野兔&#39;又赢了,[。009s [T] vs .006s [H]]。
数据在这里:http://tny.cz/64d6e5dc
它由28行约950个元素组成。其中四行总是&gt; =所有其他行。
看看性能如何适用于更大的数据集可能会很有趣。
import itertools, operator, math
import cProfile
import numpy as np
data = #SEE PASTEBIN
def tortoise(xs, ys):
all_less = True
all_greater = True
for x, y in zip(xs, ys):
if not all_less and not all_greater:
return None
if x > y:
all_less = False
elif x < y:
all_greater = False
if all_greater and all_less:
return 0
if all_greater:
return 1
if all_less:
return -1
return None # all_greater might be set False on final iteration
hare = lambda b,a : np.all(b >= a)
def find_uniques_tortoise():
include_list = range(len(data))
current_list_index = 0
while current_list_index < len(data):
if current_list_index not in include_list:
current_list_index += 1
continue
for x in range(current_list_index+1,len(data)):
if x not in include_list:
continue
result = tortoise(data[current_list_index], data[x])
if result is None: #no comparison
continue
elif result == 1 or result == 0: # this one beats the other one
include_list.remove(x)
continue
elif result == -1: #the other one beats this one
include_list.remove(current_list_index)
break
current_list_index +=1
return include_list
def find_uniques_hare():
include_list = range(len(data))
current_list_index = 0
#do all asarray()s beforehand for max efficiency
for x in range(len(data)):
data[x] = np.asarray(data[x])
while current_list_index < len(data):
if current_list_index not in include_list:
current_list_index += 1
continue
for x in range(current_list_index+1,len(data)):
if x not in include_list:
continue
if hare(data[current_list_index], data[x]): # this one beats the other one, or it's a tie
include_list.remove(x)
# print x
continue
elif hare(data[x], data[current_list_index]): #the other one beats this one
include_list.remove(current_list_index)
# print current_list_index
break
else: #no comparison
continue
current_list_index +=1
return include_list
cProfile.run('find_uniques_tortoise()')
cProfile.run('find_uniques_hare()')
print find_uniques_tortoise()
print
print find_uniques_hare()