【问题标题】:Searching items in two lists在两个列表中搜索项目
【发布时间】:2015-08-31 11:54:12
【问题描述】:

我在 python 中有两个列表,例如:

列表1:

('C2244_LNO70_SARM', '1/1/2', '1/2/8', 'CF164_LUJ70_SAR8', 'Router')
('C1723_LN270_SARM', '1/1/1', '1/1/8', 'CF164_LUJ70_SAR8', 'Router')
('CF618_JURI70_SARM', '1/1/1', '1/2/7', 'CF164_LUJ70_SAR8', 'Router')
('CF618_JURI70_SARM', '1/1/2', '1/1/1', 'CF617_LJ370_SARM', 'Router')
('C2335_ODR70_SARM', '1/1/2', '1/1/2', 'CF693_LAC70_SARM', 'Router')

列表2:

('CF618_JURI70_SARM')
('C2335_ODR70_SARM')
('CF617_LJ370_SARM')

现在,我想沿着 List1 走,如果 list2 中不存在 column0 或 column3 的值,则应删除该记录。

例如,在List1(4,3) 中,值CF693_LAC70_SARMList2 中不存在。然后可以从 List1 中删除第 4 行。

最好的方法是什么?我尝试使用if-else 条件嵌套两个for-loop,但我无法实现...

感谢任何提示...

卢卡斯

【问题讨论】:

  • 在您的示例中,将删除哪些内容,保留哪些内容?如果不匹配的 column0 或 column3 意味着该条目已被删除,则将仅保留 'CF618... CF617 项。
  • 嗨@TigerhawkT3,是的,确实,如果 col0 或 col3 中的任何值与 List2 中的任何项目都不匹配,则必须从 List1 中删除该行。因此,在我的示例中,只有 row3 CF618...CF617 将保留在 List1 中。
  • @LucasAimaretto 你有 column0 或 column3 的值不存在,这意味着如果两者都不存在,删除元组?
  • 嗨@PadraicCunningham,对不起我的英语!我的意思是:如果 List2 中不存在 col0 或 col3 值中的任何一个,则必须删除该行!在我的示例中,只有 row3 应该存在 (CF618 ... CF617)。换句话说:col0 和 col3 的值都需要存在于 List2 中。
  • @LucasAimaretto,不用担心,然后在我的答案的第二部分使用 and 或 set.issuperset。

标签: python list loops


【解决方案1】:

使用set 来存储list2 中元组中的所有字符串,并检查每个元组中的任一子元素是否在集合中:

l1=[('C2244_LNO70_SARM', '1/1/2', '1/2/8', 'CF164_LUJ70_SAR8', 'Router'),
('C1723_LN270_SARM', '1/1/1', '1/1/8', 'CF164_LUJ70_SAR8', 'Route'),
('CF618_JURI70_SARM', '1/1/1', '1/2/7', 'CF164_LUJ70_SAR8', 'Router'),
('CF618_JURI70_SARM', '1/1/2', '1/1/1', 'CF617_LJ370_SARM', 'Router'),
('C2335_ODR70_SARM', '1/1/2', '1/1/2', 'CF693_LAC70_SARM', 'Router')]

l2 = [('CF618_JURI70_SARM',),
('C2335_ODR70_SARM',),
('CF617_LJ370_SARM',)]

st = {t[0] for t in l2 }

# update original list
l1[:] = [t for t in l1 if t[0] in st or t[3] in st]

print(l1)

输出:

[('CF618_JURI70_SARM', '1/1/1', '1/2/7', 'CF164_LUJ70_SAR8', 'Router'), ('CF618_JURI70_SARM', '1/1/2', '1/1/1', 'CF617_LJ370_SARM', 'Router'), ('C2335_ODR70_SARM', '1/1/2', '1/1/2', 'CF693_LAC70_SARM', 'Router')]

我想你的意思是索引 0 和索引 3,它们是第一列和第四列。

如果 ele 0 和 ele 3 都必须存在,则使用 and:

l1[:] = [t for t in l1 if t[0] in st and t[3] in st]

这将留下一个元组,即第四个:

[('CF618_JURI70_SARM', '1/1/2', '1/1/1', 'CF617_LJ370_SARM', 'Router')]

您也可以使用set.issuperset,它测试t中的每个元素是否在s中

l1[:] = [t for t in l1 if st.issuperset([t[0],t[3]])]

print((l1))

这又会留下一个元组:

[('CF618_JURI70_SARM', '1/1/2', '1/1/1', 'CF617_LJ370_SARM', 'Router')]

一旦您的数据大小合理,构建集合的成本将被集合提供的高效0(1) 查找所抵消,因此您的代码将是0(n),而不是仅使用列表的二次方。

【讨论】:

  • @Kasra,我认为它们都是单元素元组,所以我们需要从内部获取字符串。
  • 谢谢@Padraic,in 运算符的解决方案效果很好!!
  • @LucasAimaretto,不用担心,使用列表意味着您的代码是二次的,因此对于大型输入,效率会降低,issuperset 也可以使用
【解决方案2】:

有了这些lists:

List1 = [('C2244_LNO70_SARM', '1/1/2', '1/2/8', 'CF164_LUJ70_SAR8', 'Router'),
('C1723_LN270_SARM', '1/1/1', '1/1/8', 'CF164_LUJ70_SAR8', 'Router'),
('CF618_JURI70_SARM', '1/1/1', '1/2/7', 'CF164_LUJ70_SAR8', 'Router'),
('CF618_JURI70_SARM', '1/1/2', '1/1/1', 'CF617_LJ370_SARM', 'Router'),
('C2335_ODR70_SARM', '1/1/2', '1/1/2', 'CF693_LAC70_SARM', 'Router')]
List2 = [('CF618_JURI70_SARM'),
('C2335_ODR70_SARM'),
('CF617_LJ370_SARM')]

您可以使用in 运算符过滤掉不需要的结果:

filtered_list = [item for item in List1 if item[0] in List2 and item[3] in List2]

set 操作:

List2s = set(List2)
filtered_list = [item for item in List1 if len({item[0], item[3]} & List2s) == 2]

无论哪种情况,这都会给我们留下:

>>> print(*filtered_list, sep='\n')
('CF618_JURI70_SARM', '1/1/2', '1/1/1', 'CF617_LJ370_SARM', 'Router')

【讨论】:

  • 谢谢,@TigerhawkT3。 in 运算符的解决方案就像一个魅力!问候!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
  • 2014-04-21
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多