在元组列表中,如果设置了某个字段,请找到匹配项

时间:2016-10-27 22:10:33

标签: python algorithm tuples

我有一个看起来像这样的元组列表:

[
 (36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), 
 (36, 0, 184187.125, 148323.234375, 55, 3), 
 (140, 0, 0.0, 0.0, 34, 1), 
 (141, 0, 6.35533332824707, 5.926896095275879, 22, 2)
]

我希望遍历列表,如果元组中的第二个字段是' 1',那么我想找到与第一个字段匹配的任何内容,并且将两个元组作为新元组(或其他数据结构;不必是元组)返回到匹配列表中。所以在这个例子中,输出类似于:

[(
 (36, 1, 2908.8037109375, 1835.6429443359375, 17, 0),
 (36, 0, 184187.125, 148323.234375, 55, 3)
)]

我有点不知所措从哪里开始,没有陷入非常缓慢的O(n ^ n)情况。

2 个答案:

答案 0 :(得分:1)

lst=[
 (36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), 
 (36, 0, 184187.125, 148323.234375, 55, 3), 
 (140, 0, 0.0, 0.0, 34, 1), 
 (141, 0, 6.35533332824707, 5.926896095275879, 22, 2)
]

这里有一行嵌套用于循环列表理解:

out=[y for x in lst if x[1]==1 for y in lst if y[0]==x[0]]
print(out)
[(36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), (36, 0, 184187.125, 148323.234375, 55, 3)]

如果你在lst中有很多元组,那么搜索结果会有更快的方法。

答案 1 :(得分:1)

这里有一些处理元组列表的代码,而不是假设列表已正确排序。

  • 首先根据第一个值对第二个元组列表进行排序,然后将第二个值与1进行排序(以发布布尔值),因此元组由第一个“列”“分组”,并且在元组列表中首先出现1个元组。排序不是O(n**2),可能是O(log(n)*n)
  • 然后使用groupby组合生成器表达式,根据第一个值对元组进行分组(第二个值“1”在分组时仍然是第一个)
  • 最后过滤出不存在1的组

最后一步是O(n)。这是代码:

from itertools import groupby

tuple_list = [
 (36, 0, 184187.125, 148323.234375, 55, 3),
 (140, 0, 0.0, 0.0, 34, 1),
 (141, 0, 6.35533332824707, 5.926896095275879, 22, 2),
 (36, 1, 2908.8037109375, 1835.6429443359375, 17, 0),
]

ones_first = (sorted(tuple_list,key=lambda r : (r[0],r[1]!=1)))
tuples = (tuple(x for x in y) for _,y in groupby(ones_first,key=lambda r : r[0]))

with_ones = tuple(filter(lambda r : r[0][1]==1,tuples))
print(with_ones)

结果:

(((36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), (36, 0, 184187.125, 148323.234375, 55, 3)),)