Python 在两个列表中查找特定范围内的元素

Python 在两个列表中查找特定范围内的元素,python,Python,所以我有两个列表L1是这样组成的: L1 = ['12:55:35.87', '12:55:35.70', ...] L2 = ['12:55:35.53', '12:55:35.30', ...] 我试图在两个列表中找到以相同的4个字符开头的对,即。 xx:x,然后返回每个列表的对索引 到目前为止,我已经: for pair1 in L1: for pair2 in L2: if pair1[:4] in pair2: print(L1.ind

所以我有两个列表L1是这样组成的:

L1 = ['12:55:35.87', '12:55:35.70', ...]
L2 = ['12:55:35.53', '12:55:35.30', ...]
我试图在两个列表中找到以相同的4个字符开头的对,即。 xx:x,然后返回每个列表的对索引

到目前为止,我已经:

for pair1 in L1:
    for pair2 in L2:
        if pair1[:4] in pair2:
            print(L1.index(pair1))

这似乎没有返回正确的索引,而且显然也没有返回第二个列表的索引。任何帮助都将不胜感激

以下是如何使代码正常工作。请记住,这是一个幼稚的解决方案,如果你的列表很大,有更快的方法来解决这个问题。这里的运行时间是O(n^2),但这可以在线性时间内解决

for i,pair1 in enumerate(L1):
    for j,pair2 in enumerate(L2):
        if pair1[:4] == pair2[:4]:
            print("list1: %s , list2: %s" % (i,j))
更新:对于未来的访问者,这里有一个平均线性时间解决方案:

from collections import defaultdict
l1_map = defaultdict([])

for i,val in enumerate(L1):
    prefix = val[:4]
    l1_map[prefix].append(i)


for j,val in enumerate(L2):
     prefix = val[:4]
     for l1 in l1_map[prefix]:
        print("list1: %s , list2: %s" % (l1,j))
使用for循环中的
range()
enumerate()
函数提供循环索引

例如,使用
range()
函数:

for x in range(len(L1)):
   for y in range(len(L2)):
       if L1[x][:4] == L2[y][:4]:
           print(x, y)

enumerate对于这样的事情非常有用

indexes = []
for index1, pair1 in enumerate(L1):
    pair1_slice = pair1[:4] 
    for index2, pair2 in enumerate(L2):        
        if pair1_slice == pair2[:4]:
            indexes.append([index1, index2])
            print(index1, index2)
我想这个功能就是你想要的

L1 = ['12:55:35.87', '12:55:35.70', 'spam']
L2 = ['12:55:35.53', 'eggs', '12:55:35.30']

idxs = []

for idx1, pair1 in enumerate(L1):
    for idx2, pair2 in enumerate(L2):
        if pair1[:4] == pair2[:4]:
            idxs.append((idx1, idx2))

print(idxs)
输出

[(0, 0), (0, 2), (1, 0), (1, 2)]

因为OP列表似乎有很多重复的“firsts 4个字符”,我会做如下操作:

indices = {}
for i, entry in enumerate(L1):
    indices.setdefault(entry[:4], [])
    indices[entry[:4]].append("L1-{}".format(i))
    if L2[i][:4] in indices:
        indices[L2[i][:4]].append("L2-{}".format(i))
然后,您可以通过以下方式访问重复条目:

for key in indices:
    print(key, indices[key])
这比O(n^2)好

编辑:正如有人在评论中指出的,这是假设列表的长度相同

如果没有,则假定
L2
大于
L1
,然后在执行上述操作后,可以执行以下操作:

for j, entry in enumerate(L2[i+1:]):
    indices.setdefault(entry[:4], [])
    indices[entry[:4]].append("L2-{}".format(j))
如果
L2
L1
短,只需更改所示代码中的变量名称。

您可以使用循环笛卡尔乘积

from itertools import product

L1 = ['12:55:35.87', '12:55:35.70']
L2 = ['12:55:35.53', '12:45:35.30']

res = [(i, j) for (i, x), (j, y) in 
       product(enumerate(L1), enumerate(L2)) 
       if x[:4] == y[:4]]

# [(0, 0), (1, 0)]


什么是
ra_1
ra1
?这些时间或其他数据是可以数字存储的吗?if语句应该是if pair1[:4]==pair2[:4]。还有一个更有效的方法来解决这个问题。抱歉,我修复了ra_1的东西。你还有其他例子吗?所有前4位数字都出现在所有这些字符串中。你只需要第一个索引吗?如何在线性时间内求解?你不需要检查每一个成对的组合吗?O(n^2)应该是好的,这很有效。谢谢我们可以对两个列表进行排序,然后得到O(nlogn),但我对线性也很好奇。嗯,dd:d是有限的,所以我们可以使用一个有1000个条目的表格。@gidim,伙计,这个问题是一场军备竞赛!不过你赢了我们,投一票吧@ArndtJonasson添加了线性时间解决方案这是假设两个列表具有相同的时间length@OluwafemiSule的确,修复tho很容易,请参见编辑(仍然比O(n^2)快)。如此多的相似答案如此接近,做得好!投票吧!整洁,您只执行切片
len(L1)
次!这并不能解决问题中的问题,他要求的是索引对的列表,而不是元素对本身的列表。很好,向上投票!然而,我想说的是,也许列表理解会损害可读性?是的,也许,我把它分成了三行。我现在似乎很容易理解,但可能不是每个人都喜欢。也有可能我只是不擅长一目了然地理解列表的含义&实际上很好。¯\_(ツ)_/¯