Python-比较嵌套列表并将匹配项附加到新列表?
我希望与长度不等的嵌套列表进行比较。我只对每个子列表的第一个元素之间的匹配感兴趣。如果存在匹配项,我希望将该匹配项添加到另一个列表中,以便随后转换为以制表符分隔的文件。以下是我正在使用的示例:Python-比较嵌套列表并将匹配项附加到新列表?,python,list,compare,Python,List,Compare,我希望与长度不等的嵌套列表进行比较。我只对每个子列表的第一个元素之间的匹配感兴趣。如果存在匹配项,我希望将该匹配项添加到另一个列表中,以便随后转换为以制表符分隔的文件。以下是我正在使用的示例: 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:
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']]
重新处理列表以删除重复项是一种很好的做法,还是可以用一种更简单的方式
另外,出于比较的目的,使用元组和/或元组的元组更好吗
非常感谢您的帮助
问候,,
海象的
检查数组的第二个元素是否相同。如果i[0]==j[0],则需要
否则,我发现您的代码可读性很强,不一定会对其进行更改。我不知道我是否正确解释了您的问题,但根据您的示例,您可能使用了错误的索引:
改变
if i[1] == j[1]:
进入
这里也应该使用更简单的表达式:
list_of_lists = filter(lambda l: l[0][0] == l[1][0], zip(x, y))
map(lambda l: l[1], list_of_lists)
通过使用集合,可以更简单地实现这一点
set_x = set([i[0] for i in x])
set_y = set([i[0] for i in y])
matches = list(set_x & set_y)
- 使用集合可以获取不重复的集合
- 您必须使用元组而不是列表作为项,因为集合项必须是可散列的
- 您发布的代码似乎没有生成您发布的输出。我不知道你应该如何从输入中产生输出。例如,输出有
'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()
到
- 为了将最后一次更改提升到下一个级别,我通常会替换模式
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
表示此生成器效果的另一种方法是使用生成器表达式(如果i[0]==j[0],则j代表i in x代表j in y)。
你说得对!谢谢你指出这一点。我编辑了它并展示了输出。谢谢Daniel-我不知道我可以在集合中指定索引。我认为集合只会返回列表中所有内容的完整匹配。好主意[使用集合]。但是,您应该强调,在排序和可能的重复值方面,结果将不同于原始程序的结果(这可能重要,也可能不重要,取决于结果的最终使用)。@Seafoid:索引应用于x和y的子列表,而不是任何集合。您不应使用[]在集合构造函数中。删除大括号将创建一个生成器表达式,该表达式不需要为整个列表分配内存。您如何获得上述输出?我只得到以下元素[['1','z','x']]作为输出。这比较了整个子列表,这似乎不是OP想要的。而且,我不确定这是否是我所说的更简单。我几乎总是发现使用列表理解比使用匿名函数过滤/映射更好。例如,我认为[suby For subx,如果subx==suby,则zip(x,y)中的suby]
与您的代码完全相同,但阅读起来要比过滤器和映射版本好得多。我认为[suby for subx in x for suby in y如果subx[0]==suby[0]]
更等同于OP的代码。@Mike我也喜欢列表理解,尽管函数方法有时会吸引我:-)。感谢您指出错误,现已更正。使用map
和filter
并不比使用列表理解更有效。
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