我想编写一个函数比较两个列表具有相同的长度,该函数返回两个列表,这两个列表在列表中相同位置的两个项目中是不同的 例如
如果a=[0,33,2,3,4,66,9]
和b=[0,22,2,3,4,77,9]
函数返回那两个列表因为两个元素中有不同并且每个东西都是相同的,但是如果它比较:
如果c=[0, 2,3,33,4,66,9]
b=[0,22,2,3,4,77,9]
该函数应该给我错误的结果,因为列表中不同位置的两个项目
任何帮助将不胜感激
答案 0 :(得分:4)
你也可以懒洋洋地这样做......并且在第一个n
多个不匹配的地方停下来 - 所以如果你有大量的可迭代物,你可以在你确定的时候立即停止'过多的错误匹配 - 而不是处理所有错误匹配,然后查看是否已超过阈值,例如:
from itertools import islice, izip
def no_diff_by(a, b, n):
not_equal = (False for x, y in izip(a, b) if x != y)
return next(islice(not_equal, n, None), True)
这种方式有效:
False
islice(not_equal, n, None)
并在其上调用next
,我们尝试从上面的生成器访问 nth 值
False
太多了 - 所以列表已超出匹配的阈值 - 所以我们返回False
的值( nth 项 - 因为整个生成器只返回False
)next
会返回默认值True
,而不是提升StopIteration
- 这意味着我们没有&# 39; t超过了门槛...... 答案 1 :(得分:2)
受到Jon的答案的启发,一旦达到阈值就会出现短路问题,这里有一个更简单的解决方案,并且不涉及一些疯狂的itertools魔术:
def no_diff_by(a, b, n):
for x in (1 for x, y in zip(a, b) if x != y):
n -= 1
if n < 0:
return False
return True
基本上,这使用了生成器功能(和Python 3的zip
- 你想用{2}}和Python 2)懒洋洋地得到下一个不匹配的对。对于每一对,它将计数器减1。如果我们低于零,我们发现更多的非匹配对比允许的更多,所以我们可以返回false。否则,循环将继续,直到它最终完成,此时我们可以返回true(如果你愿意,可以返回原始列表)。
答案 2 :(得分:1)
如果超出比较标准,您可以停止比较相应的元素并返回False。 else套件在for之后执行,但前提是for for normal(不是中断)。如果比较完全符合cirteria,则函数返回True。我使用break来强调for..else的动作,而不是在退出函数后中断。
def compare(list1, list2, how_many_elements_must_differ_at_the_same_position):
different_elements = 0
for x, y in zip(list1, list2):
if x != y:
different_elements += 1
if different_elements > how_many_elements_must_differ_at_the_same_position:
break
else:
if different_elements == how_many_elements_must_differ_at_the_same_position:
return True
else:
return False
return False
答案 3 :(得分:0)
好吧,我的方法是计算差异的数量然后检查它是否小于或等于2.要计数,你可以使用几种方法:带有计数器的for循环,差异列表的长度,如果元素不同,甚至是1的列表总和:
def weird_cmp(list1, list2):
if len(list1) != len(list2):
return False
number_of_differences = sum(1 for e1, e2 in zip(list1, list2) if e1 != e2)
return number_of_differences <= 2
答案 4 :(得分:0)
你可以通过列表理解来实现,
def comp_by_2_places(list1, list2):
return True if len([False for x,y in zip(a,b) if x != y])== 2 else False
希望它有帮助,,,