4

我有四个不同长度的列表。此外,每次我运行程序时,每个列表的长度都会不同。

这是 4 个可能列表的简单示例

A_list = [1, 2, 3]
B_list = [4]
C_list = [5, 6, 7, 8]
D_list = [9, 10]

我想制作一个如下所示的新列表:

answer = [[1, 4], [2, 5], [3, 6], [7, 9], [8, 10]]

到目前为止,这是我的代码。

answer = []
answer.append(list(zip(A_list, B_list)))

if len(A_list) < len(B_list):
        leftover_V_list = V_list[len(B_list):] 
        answer.append(list(zip(leftover_B_list, C_list)))

elif len(A_list) > len(B_list):
        leftover_A_list = A_list[len(B_list):]
        answer.append(list(zip(leftover_A_list, C_list)))

print(answer)

>>> 
[[(1, 4)], [(2, 5), (3, 6)]]

所以我的代码有一些问题。以下是我正在努力解决的一些问题:

  1. 我得到了正确的数字,但它们的格式错误。
  2. 我不确定如何继续 C_list 和 D_list 的其余部分
  3. 如何处理空列表的可能性

此外,我很确定我完全错了。必须有更好的方法来做到这一点。请帮忙。
我正在使用 python 3.2.3

以下是列表的一些示例:

A_list = [1]
B_list = [2, 3]
C_list = [4, 5, 6, 7]
D_list = [8]

answer =  [[1, 2], [3, 4], [5, 8], [6], [7]]

A_list = [1, 2, 3]
B_list = []
C_list = [4]
D_list = [5, 6]

answer =  [[1, 4], [2, 5], [3, 6]

A_list = [1, 2, 3]
B_list = []
C_list = []
D_list = [5, 6]

answer =  [[1,5], [2,6], [3]]

A_list = [1]
B_list = [2]
C_list = [3]
D_list = [4]

answer =  [[1, 2], [3, 4]]
4

3 回答 3

2

使用迭代器和链接:

from itertools import chain

A_iter, B_iter, C_iter, D_iter = (iter(l) for l in (A_list, B_list, C_list, D_list))
chain_a = chain(A_list, B_list)
chain_b = chain(B_list, C_list)

paired = [list(t) for t in chain(zip(chain_a, chain_b), zip(C_iter, D_iter))]

输出:

>>> A_iter, B_iter, C_iter, D_iter = (iter(l) for l in (A_list, B_list, C_list, D_list))
>>> chain_a = chain(A_iter, B_iter)
>>> chain_b = chain(B_iter, C_iter)
 >>> [list(t) for t in chain(zip(chain_a, chain_b), zip(C_iter, D_iter))]
[[1, 4], [2, 5], [3, 6], [7, 9], [8, 10]]

这也适用于空列表,因为chain只会跳过那些。

于 2013-04-12T16:15:51.510 回答
2

呸。我想我明白了。我敢肯定,这可以稍微清理一下,但它适用于所有提到的情况。它也适用于任意数量的列表,也可以处理空列表。

def remove_empties(list1):
    """removes any empty lists from our list"""
    list2 = [x for x in list1 if x]
    return list2

def merge_to_couples(new_list):
    answer = []
    new_list = remove_empties(new_list)

    while True:
        answer.append([new_list[0][0], new_list[1][0]])
        del new_list[0][0], new_list[1][0]

        new_list = remove_empties(new_list) #remove empty lists every iteration

        if len(new_list) == 0: #if length is 0, our work is done
            return answer 
        if len(new_list) == 1: #if length is 1, we need to append remaining numbers as lists with length 1
            for i in new_list[0]:
                answer.append([i])
            return answer


A_list = [1,2,3]
B_list = [4]
C_list = [5,6,7,8]
D_list = [9,10]

new_list = [A_list, B_list, C_list, D_list]

print merge_to_couples(new_list)
于 2013-04-12T19:05:09.207 回答
1

我想我可能有一个解决这个听起来可疑的问题的方法。只好求助deque

from collections import deque
from itertools import repeat, izip, izip_longest
A_list = [1, 2, 3]
B_list = [4]
C_list = [5, 6, 7, 8]
D_list = [9, 10]

def popper(x, reserve=None):
  for y in x:
    while y:
      yield y.popleft()
      while reserve:
        yield reserve.popleft()

def generate_couples(A, B, C, D):
  A = deque(izip(A, repeat(1)))
  B = deque(izip(B, repeat(2)))
  C = deque(izip(C, repeat(3)))
  D = deque(izip(D, repeat(4)))
  reserve = deque()
  a, b = popper([A, B, C, D],reserve=reserve), popper([B, C, D]) 
  for (x, y) in izip_longest(a, b):
    if not y:
      yield [x[0], None]
      continue
    while x[1] == y[1]:
      reserve.append(y)
      y = next(b)
    yield [x[0], y[0]]

print list(generate_couples(A_list, B_list, C_list, D_list))
[[1, 4], [2, 5], [3, 6], [7, 9], [8, 10]]
A_list = [1, 2, 3]
B_list = [4]
C_list = [5, 6, 7, 8, 9, 10]
D_list = [11]
print list(generate_couples(A_list, B_list, C_list, D_list))                
[[1, 4], [2, 5], [3, 6], [7, 11], [8, None], [9, None], [10, None]]
于 2013-04-12T17:59:59.620 回答