Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-比较嵌套列表并将匹配项附加到新列表?_Python_List_Compare - Fatal编程技术网

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