从两个列表应用约束中创建一个列表

时间:2014-12-23 07:27:10

标签: python list

我有两个清单A,B

A = [2,3,1,4,5,2,4]
B = [4,2,3,6,2,5,1]

我希望将A和B结合起来:

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

规则:

  1. A [i]< = B [i],取A [i],然后B [i]
  2. A [i]> B [i],取B [i],然后A [i]
  3. 我可以使用如下循环来完成此操作:

    C = []
    
    for a,b in zip(A,B):
        if(a<=b):
            C.append(a)
            C.append(b)
        else:
            C.append(b)
            C.append(a)
    

    这实际上有效。我怎么能这样做:

     C = [ [a,b if (a<=b)],[ b,a else] for a,b in zip(A,B)] # This is totally wrong
    

    但我怎么能用if-else

    来做到这一点

5 个答案:

答案 0 :(得分:5)

你做这件事的方式很好,因为它非常易读......但是如果一个单行代码就是你所追求的那样:

>>> A = [2,3,1,4,5,2,4]
>>> B = [4,2,3,6,2,5,1]
>>> [i for sublist in [[a, b] if a < b else [b, a] for a, b in zip(A, B)] for i in sublist]
[2, 4, 2, 3, 1, 3, 4, 6, 2, 5, 2, 5, 1, 4]

很少注意到:

  1. 当您向列表comp添加条件时,请在列表comp中的第一个变量之后放置if - else['a' if i in (2, 4, 16) else 'b' for i in [1, 2, 3, 16, 24]]

  2. 构建(精神上)嵌套列表推导的最佳方法是考虑如何在正常循环中编写它。


  3. C = [[a, b] if a < b else [b, a] for a, b in zip(A, B)]
    for sublist in C:
        for i in sublist:
            yield i
    

    然后你只需展平嵌套循环并将yield i移到前面,放下yield

    for sublist in C for i in sublist yield i
    |-> yield i for sublist in C for i in sublist
        |-> i for sublist in C for i in sublist
    

    现在你可以用上面的列表comp替换C并获得我发布的单行。

答案 1 :(得分:1)

使用itertools.chain.from_iterable

import itertools 
A = [2,3,1,4,5,2,4]
B = [4,2,3,6,2,5,1]  
list(itertools.chain.from_iterable(i if i[0]<=i[1] else (i[1], i[0]) for i in zip(A, B)))

或通过压缩两个列表tuple

zip(A, B)进行排序
list(itertools.chain.from_iterable(sorted(i) for i in zip(A, B)))

使用List Comprehensionmapsorted

查看时间差异
In [70]: %timeit list(itertools.chain.from_iterable(i if i[0]<=i[1] else (i[1], i[0]) for i in zip(A, B)))
100000 loops, best of 3: 3.49 µs per loop

In [71]: %timeit list(itertools.chain.from_iterable(sorted(i) for i in zip(A, B)))
100000 loops, best of 3: 5.81 µs per loop

In [72]: %timeit [i for sublist in [[a, b] if a < b else [b, a] for a, b in zip(A, B)] for i in sublist]
100000 loops, best of 3: 3.28 µs per loop

In [73]: %timeit list(itertools.chain.from_iterable(map(lambda x:x[1]>x[0] and (x[0],x[1]) or (x[1],x[0]),zip(A,B))))
100000 loops, best of 3: 4.26 µs per loop

答案 2 :(得分:1)

还是这样的?

C = sum([[a,b] if a <= b else [b, a] for (a,b) in zip(A,B)], [])

答案 3 :(得分:0)

>>> list(itertools.chain.from_iterable(map(lambda x:x[1]>x[0] and (x[0],x[1]) or (x[1],x[0]),zip(A,B))))
[2, 4, 2, 3, 1, 3, 4, 6, 2, 5, 2, 5, 1, 4]

答案 4 :(得分:-1)

你可以做到

C = [sorted([a, b]) for a, b in zip(A, B)]

并连接C的所有元素。