我希望与不等长的嵌套列表进行比较。我只对每个子列表的第一个元素之间的匹配感兴趣。如果存在匹配,我希望将匹配添加到另一个列表,以便随后转换为制表符分隔文件。以下是我正在使用的示例:
x = [['1', 'a', 'b'], ['2', 'c', 'd']]
y = [['1', 'z', 'x'], ['4', 'z', 'x']]
match = []
def find_match():
for i in x:
for j in y:
if i[0] == j[0]:
match.append(j)
return match
返回:
[['1', 'x'], ['1', 'y'], ['1', 'x'], ['1', 'y'], ['1', 'z', 'x']]
重新处理列表以删除重复项是优秀的做法还是可以更简单的方式完成?
另外,为了进行比较,使用元组和/或元组元组是否更好?
非常感谢任何帮助。
此致 Seafoid。
答案 0 :(得分:6)
使用集合获取没有重复项的集合。
您发布的代码似乎不会生成您发布的输出。我不知道你应该如何从该输入生成输出。例如,输出为'y'
,输入不为。
我认为你的功能设计可以大大改进。目前,您将x
,y
和match
定义为模块级别,并显式读取和更改它们。这不是你想要设计函数的方式 - 作为一般规则,函数不应该在全局级别改变某些东西。它应该显式传递它需要的所有内容并返回结果,而不是隐式地接收信息并改变自身之外的东西。
我会改变
x = some list
y = some list
match = []
def find_match():
for i in x:
for j in y:
if i[0] == j[0]:
match.append(j)
return match # This is the only line I changed. I think you meant
# your return to be over here?
find_match()
到
x = some list
y = some list
def find_match(x, y):
match = []
for i in x:
for j in y:
if i[0] == j[0]:
match.append(j)
return match
match = find_match(x, y)
要将最后一次更改提升到下一级别,我通常会替换模式
def f(...):
return_value = []
for...
return_value.append(foo)
return return_value
使用类似的生成器
def f(...):
for...
yield foo
将产生上述功能
def find_match(x, y):
for i in x:
for j in y:
if i[0] == j[0]:
yield j
表达此生成器效果的另一种方法是使用生成器表达式(j for i in x for j in y if i[0] == j[0])
。
答案 1 :(得分:2)
我不知道我是否正确地解释了您的问题,但是根据您的示例,您似乎可能使用了错误的索引:
变化
if i[1] == j[1]:
到
if i[0] == j[0]:
答案 2 :(得分:2)
你可以通过使用套装更简单地完成这项工作。
set_x = set([i[0] for i in x])
set_y = set([i[0] for i in y])
matches = list(set_x & set_y)
答案 3 :(得分:1)
if i[1] == j[1]
检查数组的 second 元素是否相同。你想要if i[0] == j[0]
。
否则,我发现您的代码非常易读,并且不一定会改变它。
答案 4 :(得分:0)
一个更简单的表达式也适用于此:
list_of_lists = filter(lambda l: l[0][0] == l[1][0], zip(x, y))
map(lambda l: l[1], list_of_lists)