【问题标题】:Matching values between two lists in Python?Python中两个列表之间的匹配值?
【发布时间】:2020-08-13 14:32:46
【问题描述】:

我对使用什么逻辑能够将列表与包含值的 CSV 文件/列表进行匹配感到有些困惑。我有一个想法,使用 for 循环简单地遍历 CSV 并匹配它:

for j in range(len(data)): 
    if STR_list[j] in data[j]: 
        print(data[j])

但这实际上并没有像我想要的那样打印出匹配。以下是打印时数据和 STR_list 值的样子(在上面的 for 循环之前):

print(STR_list):
['AGATC', '4', 'AATG', '1', 'TATC', '5']  

print(data)
[OrderedDict([('name', 'Alice'), ('AGATC', '2'), ('AATG', '8'), ('TATC', '3')]), OrderedDict([('name', 'Bob'), ('AGATC', '4'), ('AATG', '1'), ('TATC', '5')]), OrderedDict([('name', 'Charlie'), ('AGATC', '3'), ('AATG', '2'), ('TATC', '5')])]

因此,在这种情况下,带有“Bob”的行将是匹配的,因为值对齐。我应该为此使用正则表达式还是我认为可以使用 for 循环是正确的?

编辑:这是我打开 CSV 的方式(所以看起来它毕竟是一个列表?)

with open('file.csv') as csvfile:
reader = csv.DictReader(csvfile)
data = list(reader)

【问题讨论】:

  • 预期的输出应该是什么?你能给我们展示一下吗?
  • 我认为我的代码(for-loop)写得很糟糕,因为它的预期用途。它应该匹配 'name', 'Bob' 之后的字符串,所以最终我想在这个例子中得到名字 'Bob' 因为他将是正确的匹配项(如果这有意义的话)。
  • 我认为最好的方法是用预期的输出更新你的 OP
  • 一次遍历两个搜索词列表。第一个是名称,第二个是值。在 target 中查找元组 (name, value),其中 target 是 data 中的一个条目。
  • 顺便说一句,我有一个基于 collections.namedtuple 的查找字典的工作解决方案,尽管为每个字段使用 defaultdict(set) 会更好。

标签: python list csv format match


【解决方案1】:
if STR_list[j] in data[j]: 

这一行应该被标记在 for 循环中。假设这是一个复制/粘贴错误:

STR_list[j] 没有查看整个 STR_list,只查看其中的第 j 个项目(因此,当您查看 data[0] 时,您正在查看“AGATC”,当您查看 data[ 1] 您正在查看“4”等)。

你想要的是寻找所有的STR_list,看看它是否在每次检查数据的第2、3、4位。

此外,STR_list 的格式需要与数据相同,因此您需要一个元组列表(或 OrderedDict,我不熟悉该数据类型,所以我不知道这是否完全是什么组成数据)。

真的,您要查找的内容相当于:

如果 [('AGATC', '2'), ('AATG', '8'), ('TATC', '3')] 在 OrderedDict([('name', 'Alice' ), ('AGATC', '2'), ('AATG', '8'), ('TATC', '3')])

我知道我没有给你确切的代码,但我希望我解释它以便你自己理解和弄清楚。

【讨论】:

  • 谢谢!我正试图绕过它,我也无法将我的 STR_list 设置为 OrderedDict,因此它们的输出如下所示: print(STR_odict): OrderedDict([('AGATC', '4' ), ('AATG', '1'), ('TATC', '5')]) 打印(数据):[OrderedDict([('name', 'Alice'), ('AGATC', '2' ), ('AATG', '8'), ('TATC', '3')]), OrderedDict([('name', 'Bob'), ('AGATC', '4'), ('AATG ', '1'), ('TATC', '5')]), OrderedDict([('name', 'Charlie'), ('AGATC', '3'), ('AATG', '2' ), ('TATC', '5')])] 我越来越近了。
  • 您是否也更改了 for 循环?你的 for 循环代码和现在的输出是什么?
  • 仍在尝试解决...看来我的数据值实际上是一个列表,而不是 OrderedDict。这很混乱。
  • 这应该意味着数据是元组列表的列表,我将表示为 -> [[(,),(,),(,),(,)],[( ,),(,),(,),(,)]] 您的 for 循环正在遍历外部列表,为您提供每次迭代检查的元组列表 -> [(,),(,), (,),(,)] 这意味着你希望你的 STR_list 也是一个元组列表 -> [(,),(,),(,)] 但这是一个比你的数据更短的元组列表[j]列表,因此您需要查看数据的子集[j]
  • 我(想我)明白了。我认为让我感到困惑的是如何访问数据中的子集。 data[0] 打印: OrderedDict([('name', 'Alice'), ('AGATC', '2'), ('AATG', '8'), ('TATC', '3')] ) STR_list[0] 打印: ('AGATC', '4') 例如,我不明白如何隔离 data[0] 中的不同元素。我也不明白为什么它在被列入列表时带有“OrderedDict”,因为虽然两者看起来相同,但它们并不像一个是一个列表而不是一个列表。令人沮丧。
【解决方案2】:
for j in range(len(data)):
    #we flatten the OrderedDict into a list
    flattened_data = [x for item in data[j].items() for x in item]
    #Now we verify that the list STR_list and the list flattened_data (minus the 2 first element, aka "name" and the actual name) are equal
    if sum([1 for x1, x2 in zip(STR_list, flattened_data[2:]) if x1 == x2])==len(STR_list):
       #Now we print the name of the person which is at index 1 inside the new list
       print(flattened_data[1])
    
 

基本上你需要学习如何比较两个列表以及如何从列表中选择特定元素

【讨论】:

  • 我正在尝试,这是我第一次尝试 Python(而且我在 4 周前才开始使用代码)。不过,我应该添加我的 CSV 打开代码,因为我的数据变量似乎已经是一个列表,这意味着它没有项目: with open('file.csv') as csvfile: reader = csv.DictReader(csvfile) data = list (读者)
猜你喜欢
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多