关于python:迭代两个列表并同步它们

Iterate on two lists and sync them

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

伪代码:

1
2
3
4
5
6
j=1
for i=1 to n:
   print a[i], b[j]
   while b[j+1] <= a[i]:
      j++
      print a[i], b[j]

例如:

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

期望输出:

1
2
3
4
5
1 2
3 2
5 2
5 4
7 4

你如何在Python中干净地完成它?


您的伪代码几乎可以在Python中使用。执行所需操作的一些工作代码是:

1
2
3
4
5
6
7
8
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中进行的一些更改:

  • 声明列表时,项之间需要逗号。
  • 列表索引从0开始,所以ij都应该从0开始。
  • len(a)返回a的长度(本例为4),通过range(len(a))迭代i0len(a)-1的每个整数执行循环,这是a中的所有索引。
  • python不支持++操作,所以我们改用j +=1操作。
  • 我们必须避免使用b的越界指数,因此我们测试以确保j在递增之前处于越界状态。
  • 通过如下迭代列表,可以使此代码更具pythonic性:

    1
    2
    3
    4
    5
    6
    7
    8
    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]

    一般来说,您可能不希望只打印列表元素,因此对于更一般的用例,您可以创建一个生成器,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    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])

    然后你可以像以前一样用

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


    murgatroid99答案中的生成器代码可以通过使用next()而不是索引算法概括为任何iterables(与仅序列相反):

    1
    2
    3
    4
    5
    6
    7
    8
    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