迭代两个列表并同步它们

时间:2012-08-06 17:08:58

标签: python iteration

我需要以下列方式迭代两个列表:

伪代码:

j=1
for i=1 to n:
   print a[i], b[j]
   while b[j+1] <= a[i]:
      j++
      print a[i], b[j]

例如:

a = [1 3 5 7]
b = [2 4 9] 

期望的输出:

1 2
3 2
5 2
5 4
7 4

你如何在python中干净利落地做到这一点?

2 个答案:

答案 0 :(得分:7)

您的伪代码几乎可以在Python中运行。一些可以满足您需求的工作代码:

a = [1, 3, 5, 7]
b = [2, 4, 9] 
j = 0
for i in range(len(a)):
    print a[i], b[j]
    while j<len(b)-1 and b[j+1] <= a[i]:
        j += 1
        print a[i], b[j]

请注意一些使其在Python中有效的更改:

  1. 声明列表时,项目之间需要逗号。
  2. 列表索引从0开始,因此ij都应该从那里开始。
  3. len(a)返回a的长度(本例中为4),迭代irange(len(a))执行从0到每个整数的循环len(a)-1,这是a
  4. 中的所有索引
  5. Python不支持++操作,因此我们改用j +=1
  6. 我们必须避免使用b的超出范围索引,因此我们进行测试以确保j在递增之前将处于边界内。
  7. 通过按如下方式遍历列表,可以使此代码更加pythonic:

    a = [1, 3, 5, 7]
    b = [2, 4, 9] 
    j = 0
    for element in a:
       print element, b[j]
       while j<len(b)-1 and b[j+1] <= element:
          j += 1
          print element, b[j]
    

    通常,您可能不希望只打印列表元素,因此对于更一般的用例,您可以创建generator,如:

    def sync_lists(a, b)
        if b:
            j = 0
            for element in a:
                yield (element, b[j])
                while j<len(b)-1 and b[j+1] <= element:
                    j += 1
                    yield (element, b[j])
    

    然后你可以像以前一样用

    打印它们
    a = [1, 3, 5, 7]
    b = [2, 4, 9]
    for (e1, e2) in sync_lists(a, b):
        print e1, e2
    

答案 1 :(得分:2)

murgatroid99's answer中的生成器代码可以通过使用next()而不是索引算法推广到任何迭代(而不是仅序列):

def sync_list(a, b):
    b = iter(b)
    y, next_y = next(b), next(b)
    for x in a:
       yield x, y
       while next_y <= x:
          y, next_y = next_y, next(b)
          yield x, y