2012-08-06 60 views
3

我需要在两个列表迭代以下列方式:迭代两个列表,并同步他们

伪代码:

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 

你是怎么做的呢cl在python中是否可以使用?

+3

这个问题似乎不完全对我来说,可以根据你解释你的输出两个输入列表? '9'发生了什么? – Levon 2012-08-06 17:13:31

+0

@Levon'9'不会显示在伪代码的输出中,就像我翻译的Python所显示的那样。 – murgatroid99 2012-08-06 17:25:12

回答

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在这种情况下),并通过迭代range(len(a))i执行用于每个整数从0len(a)-1,这是所有索引的在a循环。
  4. Python中不支持++操作,因此我们使用j +=1代替。
  5. 我们必须避免使用b的出界指数,所以我们测试以确保j在递增之前处于界限内。

该代码可以通过列表迭代进行更Python如下:

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 
如之前打印出来
+0

是的,这看起来很不寻常,以至于伪代码的直接翻译可能比一些使用'next'和'itertools'的游戏更简单。不过,我可能会将这种迭代逻辑封装在一个生成器中,这在我看来是最古怪的迭代逻辑的Pythonic“家”。 – DSM 2012-08-06 17:25:00

+0

@DSM这是一个很好的观点,我将添加一个迭代器版本。 – murgatroid99 2012-08-06 17:26:17

+0

我很好奇 - 你推荐使用'enumerate',但它看起来不像你使用'i'。只是遍历列表不是更容易吗? – 2012-08-06 17:35:06

2

murgatroid99's answer生成器代码可以推广到任何iterables使用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 
+0

请注意,对于错误的数组,您可能会开始出现StopIteration异常。我修改了我的代码以避免相应的IndexError。 – murgatroid99 2012-08-07 13:09:16

+1

@ murgatroid99:'StopIteration'由调用者处理,例如for循环。发生器中“错误”阵列不需要特殊处理。 – jfs 2012-08-07 13:24:08

+0

@ J.F.Sebastian,但'b'没有在for循环中迭代,所以调用者*是*'sync_list'。调用['next'](http://docs.python.org/library/functions.html#next)可以引发该异常,并且在循环中使用它不会神奇地处理它。 – murgatroid99 2012-08-07 13:26:19