我想从一个压缩列表(ziped_list(创建一个列表,但只考虑另一个列表(other(的元素。
两个基本列表是:
base1 = [['A', 'B'], ['B'], ['A', 'B', 'C', 'D', 'E'], ['B'], ['A', 'B', 'C'], ['A'], ['B', 'C'], ['A', 'B'],
['C', 'A', 'B'], ['A'], ['B', 'C']]
base2 = [[1.0, 5.0], [3.0], [2.0, 7.0, 3.0, 1.0, 6.0], [3.0], [5.0, 2.0, 3.0], [1.0], [9.0, 3.0], [2.0, 7.0],
[3.0, 6.0, 8.0], [2.0], [7.0, 9.0]]
- 压缩列表创建如下:
ziped_list = list(zip(base1, base2))
看起来像这样:
[(['A', 'B'], [1.0, 5.0]),
(['B'], [3.0]),
(['A', 'B', 'C', 'D', 'E'], [2.0, 7.0, 3.0, 1.0, 6.0]),
(['B'], [3.0]),
(['A', 'B', 'C'], [5.0, 2.0, 3.0]),
(['A'], [1.0]),
(['B', 'C'], [9.0, 3.0]),
(['A', 'B'], [2.0, 7.0]),
(['C', 'A', 'B'], [3.0, 6.0, 8.0]),
(['A'], [2.0]),
(['B', 'C'], [7.0, 9.0])]
- 其他(参考(列表为:
other = ['A', 'B']
预期结果是:
[(['A', 'B'], [1.0, 5.0]),
(['B'], [3.0]),
(['A', 'B'], [2.0, 7.0]),
(['B'], [3.0]),
(['A', 'B'], [5.0, 2.0]),
(['A'], [1.0]),
(['B'], [9.0]),
(['A', 'B'], [2.0, 7.0]),
(['A', 'B'], [6.0, 8.0]),
(['A'], [2.0]),
(['B'], [7.0])]
我尝试了以下代码,但没有像我预期的那样工作:
otherSet = set(other)
result = [[x for x in arr if x in otherSet] for arr in ziped_list[:][0]]
result
如果你能详细说明如何修复我的代码或找到另一种Python方法,那将是很有帮助的。
以下是如何:
base1 = [['A', 'B'], ['B'], ['A', 'B', 'C', 'D', 'E'], ['B'], ['A', 'B', 'C'], ['A'], ['B', 'C'], ['A', 'B'], ['C', 'A', 'B'], ['A'], ['B', 'C']]
base2 = [[1.0, 5.0], [3.0], [2.0, 7.0, 3.0, 1.0, 6.0], [3.0], [5.0, 2.0, 3.0], [1.0], [9.0, 3.0], [2.0, 7.0], [3.0, 6.0, 8.0], [2.0], [7.0, 9.0]]
other = ['A', 'B']
lst1 = [[(a,i) for i,a in enumerate(l) if a in other] for l in base1] # List of letters with index
lst2 = [[l[i] for b,i in a] for a,l in zip(lst1,base2)] # List of numbers found by using the indexes in lst1
lst1 = [[s[0] for s in l] for l in lst1] # Remove index from letters
lst = [(a, b) for a, b in zip(lst1, lst2)] # Zip up list of letters and list of numbers
print(lst)
输出:
[(['A', 'B'], [1.0, 5.0]),
(['B'], [3.0]),
(['A', 'B'], [2.0, 7.0]),
(['B'], [3.0]),
(['A', 'B'], [5.0, 2.0]),
(['A'], [1.0]),
(['B'], [9.0]),
(['A', 'B'], [2.0, 7.0]),
(['A', 'B'], [6.0, 8.0]),
(['A'], [2.0]),
(['B'], [7.0])]
更新:
以下是如何使用operator.itemgetter()
:
from operator import itemgetter as ig
base1 = [['A', 'B'], ['B'], ['A', 'B', 'C', 'D', 'E'], ['B'], ['A', 'B', 'C'], ['A'], ['B', 'C'], ['A', 'B'], ['C', 'A', 'B'], ['A'], ['B', 'C']]
base2 = [[1.0, 5.0], [3.0], [2.0, 7.0, 3.0, 1.0, 6.0], [3.0], [5.0, 2.0, 3.0], [1.0], [9.0, 3.0], [2.0, 7.0], [3.0, 6.0, 8.0], [2.0], [7.0, 9.0]]
other = ['A', 'B']
idx = [[i for i,a in enumerate(l) if a in other] for l in base1] # Nested list of indexes
lst1 = [ig(*i)(l) for l, i in zip(base1, idx)] # List of letters
lst2 = [ig(*i)(l) for l, i in zip(base2, idx)] # List of numbers
lst = [(a, b) for a, b in zip(lst1, lst2)] # Zip the list of letters and numbers
您可以再次应用zip
来过滤:
base1 = [['A', 'B'], ['B'], ['A', 'B', 'C', 'D', 'E'], ['B'], ['A', 'B', 'C'], ['A'], ['B', 'C'], ['A', 'B'], ['C', 'A', 'B'], ['A'], ['B', 'C']]
base2 = [[1.0, 5.0], [3.0], [2.0, 7.0, 3.0, 1.0, 6.0], [3.0], [5.0, 2.0, 3.0], [1.0], [9.0, 3.0], [2.0, 7.0], [3.0, 6.0, 8.0], [2.0], [7.0, 9.0]]
other = ['A', 'B']
result = [list(zip(*[[j,k] for j, k in zip(a, b) if j in other])) for a, b in zip(base1, base2)]
输出:
[[('A', 'B'), (1.0, 5.0)],
[('B',), (3.0,)],
[('A', 'B'), (2.0, 7.0)],
[('B',), (3.0,)],
[('A', 'B'), (5.0, 2.0)],
[('A',), (1.0,)],
[('B',), (9.0,)],
[('A', 'B'), (2.0, 7.0)],
[('A', 'B'), (6.0, 8.0)],
[('A',), (2.0,)],
[('B',), (7.0,)]]