Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不具有相同索引的列表的python交集_Python - Fatal编程技术网

不具有相同索引的列表的python交集

不具有相同索引的列表的python交集,python,Python,我有一个奇怪的情况,过了一段时间我还没有想出一个适当的解决办法 假设您有两个列表,并且需要查找具有相同索引的项 x = [1,4,5,7,8] y = [1,3,8,7,9] 通过使用以下方法,我能够获得具有相同索引的两个列表中出现的内容的正确交集: matches = [i for i, (a,b) in enumerate(zip(x,y)) if a==b) 这将返回: [0,3] 我可以通过以下方法得到两个列表的简单交集(在许多其他方面,这只是一个示例) 这将返回以下列表: [1,

我有一个奇怪的情况,过了一段时间我还没有想出一个适当的解决办法

假设您有两个列表,并且需要查找具有相同索引的项

x = [1,4,5,7,8]
y = [1,3,8,7,9]
通过使用以下方法,我能够获得具有相同索引的两个列表中出现的内容的正确交集:

matches = [i for i, (a,b) in enumerate(zip(x,y)) if a==b)
这将返回:

[0,3]
我可以通过以下方法得到两个列表的简单交集(在许多其他方面,这只是一个示例)

这将返回以下列表:

[1,8,7,9]
问题是。我想知道一些关于获取项目列表(如第二个列表)的想法,这些项目不包括上面的匹配项,但在列表中不在同一位置

换句话说,我在x中查找在y中不共享相同索引的项

期望的结果是y中的索引位置“8”,或
[2]


提前感谢

你离得太近了:反复浏览
y
;查找位于
x
但不在同一位置的值:

offset = [i for i, a in enumerate(y) if a in x and a != x[i] ]
结果:

[2]
包括建议从
pault
升级到
Martijn的
comment。。。如果列表较大,预处理可降低复杂性:

>>> both = set(x) & set(y)
>>> offset = [i for i, a in enumerate(y) if a in both and a != x[i] ]

正如PaulT指出的,这在OP发布的级别上仍然是相当可读的。

你太接近了:通过
y
迭代;查找位于
x
但不在同一位置的值:

offset = [i for i, a in enumerate(y) if a in x and a != x[i] ]
结果:

[2]
包括建议从
pault
升级到
Martijn的
comment。。。如果列表较大,预处理可降低复杂性:

>>> both = set(x) & set(y)
>>> offset = [i for i, a in enumerate(y) if a in both and a != x[i] ]

正如PaulT所指出的,在OP的发布级别,这仍然是非常可读的。

我会为第一个列表创建一个索引字典,然后使用它来测试第二个值是否是该字典中的a)和b)当前索引不存在:

def non_matching_indices(x, y):
    x_indices = {}
    for i, v in enumerate(x):
        x_indices.setdefault(v, set()).add(i)

    return [i for i, v in enumerate(y) if i not in x_indices.get(v, {i})]
上述过程需要
O(len(x)+len(y))
时间;在一个列表中进行一次完整扫描,然后在另一个列表中进行另一次完整扫描,其中包含
i
的每个测试都在固定时间内完成

在这里,您确实不想在x
包容测试中使用
值,因为这需要对
x
进行扫描(循环),以查看该值是否真的在列表中。这需要
O(len(x)
时间,并且对
y
中的每个值都要这样做,这意味着函数需要
O(len(x)*len(y)
时间

当您运行一个包含随机数据的较大列表的计时试验时,您可以看到速度差异:

>>> import random, timeit
>>> def using_in_x(x, y):
...     return [i for i, a in enumerate(y) if a in x and a != x[i]]
...
>>> x = random.sample(range(10**6), 1000)
>>> y = random.sample(range(10**6), 1000)
>>> for f in (using_in_x, non_matching_indices):
...     timer = timeit.Timer("f(x, y)", f"from __main__ import f, x, y")
...     count, total = timer.autorange()
...     print(f"{f.__name__:>20}: {total / count * 1000:6.3f}ms")
...
          using_in_x: 10.468ms
non_matching_indices:  0.630ms

因此,对于每个1000个数字的两个列表,如果您在x测试中使用
值,则完成任务所需的时间很容易达到15倍。

我会为第一个列表创建索引字典,然后使用该字典测试第二个值是否为a)在该字典中,以及b)当前索引是否不存在:

def non_matching_indices(x, y):
    x_indices = {}
    for i, v in enumerate(x):
        x_indices.setdefault(v, set()).add(i)

    return [i for i, v in enumerate(y) if i not in x_indices.get(v, {i})]
x = [1,4,5,7,8]
y = [1,3,8,7,9]

result=[]
for e in x:
    if e in y and x.index(e) != y.index(e):
        result.append((x.index(e),y.index(e),e))

print result  #gives tuple with x_position,y_position,value
上述过程需要
O(len(x)+len(y))
时间;在一个列表中进行一次完整扫描,然后在另一个列表中进行另一次完整扫描,其中包含
i
的每个测试都在固定时间内完成

在这里,您确实不想在x
包容测试中使用
值,因为这需要对
x
进行扫描(循环),以查看该值是否真的在列表中。这需要
O(len(x)
时间,并且对
y
中的每个值都要这样做,这意味着函数需要
O(len(x)*len(y)
时间

当您运行一个包含随机数据的较大列表的计时试验时,您可以看到速度差异:

>>> import random, timeit
>>> def using_in_x(x, y):
...     return [i for i, a in enumerate(y) if a in x and a != x[i]]
...
>>> x = random.sample(range(10**6), 1000)
>>> y = random.sample(range(10**6), 1000)
>>> for f in (using_in_x, non_matching_indices):
...     timer = timeit.Timer("f(x, y)", f"from __main__ import f, x, y")
...     count, total = timer.autorange()
...     print(f"{f.__name__:>20}: {total / count * 1000:6.3f}ms")
...
          using_in_x: 10.468ms
non_matching_indices:  0.630ms
因此,如果您在x
测试中使用
value,那么对于两个分别有1000个数字的列表,您很容易需要15倍的时间来完成任务

x = [1,4,5,7,8]
y = [1,3,8,7,9]

result=[]
for e in x:
    if e in y and x.index(e) != y.index(e):
        result.append((x.index(e),y.index(e),e))

print result  #gives tuple with x_position,y_position,value
此版本逐项浏览第一个列表,并检查该项目是否也在第二个列表中。如果是,则比较两个列表中找到的项的索引,如果它们不同,则将两个索引和项值存储为一个元组,在结果列表中有三个值


此版本逐项浏览第一个列表,并检查该项目是否也在第二个列表中。如果是,它将比较两个列表中找到的项目的索引,如果它们不同,则将两个索引和项目值存储为一个元组,在结果列表中有三个值。

“换句话说,我在x中查找的项目在y中不共享同一索引”-您是指
x
y
中不共享同一索引的项目吗?是的,确实如此。当您获得解决方案时,请记住向上投票有用的内容并接受您最喜欢的答案(即使您必须自己编写),这样堆栈溢出可以正确存档问题。“换句话说,我正在寻找x中与y中索引不相同的项目”-你是指
x
y
中与y中索引不相同的项目吗?是的,确实如此。当你得到解决方案时,请记得投票选出有用的项目,并接受你最喜欢的答案(即使你必须自己写),因此堆栈溢出可以正确地存档问题。这会对
x
进行二次扫描,每个
a in x
测试都必须迭代
x
,以查看是否存在匹配项。是的,它是二次的。根据OP的尝试,不太高级的程序员也可以访问它。不过,您选择了高性能的测试,这是很好的e“学习延伸”和一个更有效的算法,用于处理大型列表。谢谢,这正是我想要的。我尝试了无数种不同的方法,但我的大脑停止了对我的思考。不客气……但我建议你阅读Martijn的答案(以及他的评论)并从中学习。您可以预计算交叉点以避免二次查找。这将对
x
进行二次扫描,x
测试中的每个
a必须迭代
x
,以查看是否存在匹配项。