2014-12-23 29 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

相關問題