簡體   English   中英

Python List comprehension使用條件從列表創建不等長度列表

[英]Python List comprehension to create unequal length lists from a list using conditional

使用列表推導,itertools或類似函數,是否可以根據條件從列表中創建兩個不相等的列表? 這是一個例子:

main_list = [6, 3, 4, 0, 9, 1]
part_list = [4, 5, 1, 2, 7]

in_main = []
out_main = []

for p in part_list:
  if p not in main_list:
    out_main.append(p)
  else:
    in_main.append(p)

print out_main
print in_main

>>> [5, 2, 7]
>>> [4, 1]

試圖保持簡單,但作為使用示例,main_list可以是包含字典鍵的part_list的字典中的值。 需要同時生成兩個列表。 心連心。

只要您沒有重復數據,訂單無關緊要。

main_set = set([6, 3, 4, 0, 9, 1])
part_set = set([4, 5, 1, 2, 7])

out_main = part_set - main_set
in_main = part_set & main_set

任務完成。

如果訂單(在part_list中)很重要:

out_main = [p for p in part_list if p not in main_list]
in_main = [p for p in part_list if p in main_list]

除此以外:

out_main = list(set(part_list) - set(main_list))
in_main = list(set(part_list) & set(main_list))

基於itertools的真正解決方案,適用於可迭代的:

>>> part_iter = iter(part_list)
>>> part_in, part_out = itertools.tee(part_iter)
>>> in_main = (p for p in part_in if p in main_list)
>>> out_main = (p for p in part_out if p not in main_list)

從這些列表中創建列表會使用迭代器失敗,但結果如下:

>>> list(in_main)
[4, 1]
>>> list(out_main)
[5, 2, 7]

這具有從另一個延遲生成的序列延遲生成in_mainout_main的優點。 唯一的問題是,如果你在另一個之前迭代一個,那么tee必須緩存一堆數據,直到另一個迭代器使用它為止。 因此,只有在大致相同的時間迭代它們時,這才真正有用。 否則你不妨自己使用輔助存儲。

還有一個有趣的三元運算符解決方案。 (你可以將它壓縮成列表理解,但這是錯誤的。)我將main_list更改為O(1)查找的集合。

>>> main_set = set(main_list)
>>> in_main = []
>>> out_main = []
>>> for p in part_list:
...     (in_main if p in main_set else out_main).append(p)
... 
>>> in_main
[4, 1]
>>> out_main
[5, 2, 7]

還有一個有趣的collections.defaultdict方法:

>>> import collections
>>> in_out = collections.defaultdict(list)
>>> for p in part_list:
...     in_out[p in main_list].append(p)
... 
>>> in_out
defaultdict(<type 'list'>, {False: [5, 2, 7], True: [4, 1]})
in_main = list(set(main_list) & set(part_list))
out_main = list(set(part_list) - set(in_main))

從謂詞列表開始:

test_func = [part_list.__contains__, lambda x: not part_list.__contains__(x)]
# Basically, each of the predicates is a function that returns a True/False value     
# (or similar) according to a certain condition.
# Here, you wanted to test set intersection; but you could have more predicates.

print [filter(func, main_list) for func in test_func]

然后你有了“一線”,但是通過維護一個謂詞列表你會有一些開銷工作

正如在其他答案中所說,你可以通過使用set(main_list)來加速查找set(main_list)不是在列表理解中,而是在之前)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM