比较等长列表以查找共享相同元素的位置

时间:2011-04-15 16:26:20

标签: python list elements

我想比较长度相同但内容不同的列表列表。我的脚本应仅返回共享完全相同元素的位置(在所有列表中)。 例如:

l = [[1,2,3,4,5,6,7,8],[9,8,8,4,3,4,5,7,8],[5,6,7 ,4,9,9,9,8],[0,0,1,4,7,6,3,8]]

因此我获得了一个位置列表p = [3,7],因为在所有列表中我们分别在第3和第7位有'4'和'8'。

这些元素也可以是字符串,我只是给出一个整数的例子。谢谢你的帮助!

4 个答案:

答案 0 :(得分:4)

l = [[1,2,3,4,5,6,7,8],[9,8,8,4,3,4,5,7,8],[5,6,7,4,9,9,9,8],[0,0,1,4,7,6,3,8]]

p = [i for i, j in enumerate(zip(*l)) if all(j[0]==k for k in j[1:])]

# p == [3] - because of some typo in your original list, probably too many elements in the second list.

这只是一个单行(列表理解)版本,更详细:

p = []
for i, j in enumerate(zip(*l)):
    if all(j[0]==k for k in j[1:]):
        p.append(i)

zip(*l)为您提供:

[(1, 9, 5, 0),
 (2, 8, 6, 0),
 (3, 8, 7, 1),
 (4, 4, 4, 4),
 (5, 3, 9, 7),
 (6, 4, 9, 6),
 (7, 5, 9, 3),
 (8, 7, 8, 8)]

enumerate()将数字0,1,2,......放入该列表中的每个元组。

all(j[0]==k for k in j[1:])将元组的第一个元素与所有剩余元素进行比较,如果所有元素都相等则返回True,否则返回False(它会尽快返回False它找到一个不同的元素,所以它更快)

答案 1 :(得分:2)

我喜欢eumiro解决方案,但我做了一套

p = [i for i, j in enumerate(zip(*l)) if len(set(j)) == 1]

答案 2 :(得分:0)

l = [[1,2,3,4,5,6,7,8],[9,8,8,4,3,4,5,7,8],[5,6,7,4,9,9,9,8],[0,0,1,4,7,6,3,8]]
r = []

for i in range(len(l[0])):
    e = l[0][i]
    same = True
    for j in range(1, len(l)):
        if e != l[j][i]:
            same = False
            break
    if same:
        r.append(i)

print r

仅打印[3],因为l [1]在位置7处没有8。它还有一个元素。

答案 3 :(得分:0)

li = [[1,2,3,4,5,6,7,8],[9,8,8,4,3,6,5,8],[5,6,7,4,9,9,9,8],[0,0,1,4,7,6,3,8]]

first = li[0]
r = range(len(first))
for current in li[1:]:
    r = [ i for i in r if current[i]==first[i]]

print [first[i] for i in r]

结果

[4, 8]

比较执行时间:

from time import clock

li = [[1,2,3,4,5,6,7,8,9,10],
      [9,8,8,4,5,6,5,8,9,13],
      [5,6,7,4,9,9,9,8,9,12],
      [0,0,1,4,7,6,3,8,9,5]]

n = 10000

te = clock()
for turn in xrange(n):
    first = li[0]
    r = range(len(first))
    for current in li[1:]:
        r = [ i for i in r if current[i]==first[i]]
    x = [first[i] for i in r]
t1 = clock()-te
print 't1 =',t1
print x


te = clock()
for turn in xrange(n):
    y = [j[0] for i, j in enumerate(zip(*li)) if all(j[0]==k for k in j[1:])] 
t2 = clock()-te
print 't2 =',t2
print y

print 't2/t1 =',t2/t1
print

结果

t1 = 0.176347273187
[4, 8, 9]
t2 = 0.579408755442
[4, 8, 9]
t2/t1 = 3.28561221827

使用

li = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,2,22,26,24,25],
      [9,8,8,4,5,6,5,8,9,13,18,12,15,14,15,15,4,16,19,20,2,158,35,24,13],
      [5,6,7,4,9,9,9,8,9,12,45,12,4,19,15,20,24,18,19,20,2,58,23,24,25],
      [0,0,1,4,7,6,3,8,9,5,12,12,12,15,15,15,5,3,14,20,9,18,28,24,14]]

结果

t1 = 0.343173188632
[4, 8, 9, 12, 15, 20, 24]
t2 = 1.21259110432
[4, 8, 9, 12, 15, 20, 24]
t2/t1 = 3.53346690385