2014-12-23 27 views
3

我有两个表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]

我可以做到这一点使用循环象下面这样:

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

你正在做的是好事,因为它是非常具有可读性的方式......但如果一个-liner是你是什么之后,我将迫使:

>>> 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. 当您添加一个有条件的list comp,在列表comp中的第一个变量之后有if - else['a' if i in (2, 4, 16) else 'b' for i in [1, 2, 3, 16, 24]]

  2. 构建(精神上)嵌套列表解析的最好方法就是想想如何在正常循环中编写它。


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 

现在你可以用上面的列表组件替换C,并获得我发布的单行代码。

+0

哦的所有元素..非常感谢你。这是你的答案。我得到它为子列表中的子列表 – aerokite

+0

我在子列表我和我的子列表在C列我在子列表中 - 我可以使用两个吗? – aerokite

+0

不,对于子列表中的item_in_sublist,C的子列表item_in_sublist是**正确的**和**有效的**语法。 – sberry

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 Comprehensionmap看时间diffrence,sorted

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 
+0

谢谢,先生。 – aerokite

+0

我认为随着元素数量的增加,itertools解决方案比我发布的嵌套for循环解决方案获得更高性能。但从我记得的情况来看,它需要一个相当大的数据集。尽管如此,我个人仍然更喜欢itertools解决方案。我最喜欢的模块之一。 – sberry

+0

@sberry在列表中的大项目中,itertools首选这就是为什么我在这里使用'itertools'。 –

1

或者类似的东西?

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

你很聪明.. :) – aerokite

-1

你可以做

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

并连接C.

+0

这是你的结果:[[2,4],[2,3],[1,3],[4,6],[2,5],[2,5] ,[1,4]] – aerokite

+0

C的元素必须连接以产生最终结果。你不看完整的帖子? – VinyleEm

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] 
+0

我没有明白。你能解释一下吗? – aerokite

相关问题